I have an issue with our firm's Normal.dotm related to the eastAsia attribute in styles.xml. If you're interested, you can find a history of the issue here. We can't just replace the template firmwide without overwriting custom styles/macros, etc. I have almost no experience with OpenXML, but I thought it might hold a solution to the problem. However, all the articles and tutorials I've found haven't been much help. They all reference the "Document" part and are focused on changing content rather than elements and attributes.
Basically, I need to loop through every <w:rFonts> element and change the w:eastAsia attribute from "Times New Roman" to "MS Mincho." This is the only part I feel confident about:
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Packaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace eastAsiaFix
{
class Program
{
static void Main(string[] args)
{
using (WordprocessingDocument myDocument = WordprocessingDocument.Open(#"C:\users\" + Environment.UserName + #"\Desktop\eastAsiaFix.dotm", true))
{
StyleDefinitionsPart styles = myDocument.MainDocumentPart.StyleDefinitionsPart;
if (styles == null)
{
return;
}
}
}
}
}
I think what I need is something like the following:
foreach (OpenXMLElement theStyle in styles.Styles.ChildElements)
{
if (theStyle.LocalName = "style")
{
theStyle.StyleRunProperties.RunFonts.EastAsia.Value = "MS Mincho"; //faking this
}
}
How do I get to the w:rFonts node and edit the eastAsia attribute?
I can think of two different solutions to change the East Asian font value.
The first solution just changes the East Asian font value for all RunFonts
under the Styles collection. This solutions would also change the East Asian
font value for the document default paragraph and run properties (DocDefaults class, w:docDefaults).
using (WordprocessingDocument myDocument = WordprocessingDocument.Open(#"C:\users\" + Environment.UserName + #"\Desktop\eastAsiaFix.dotm", true))
{
StyleDefinitionsPart stylesPart = myDocument.MainDocumentPart.StyleDefinitionsPart;
if (stylesPart == null)
{
Console.Out.WriteLine("No styles part found.");
return;
}
foreach(var rf in stylesPart.Styles.Descendants<RunFonts>())
{
if(rf.EastAsia != null)
{
Console.Out.WriteLine("Found: {0}", rf.EastAsia.Value);
rf.EastAsia.Value = "MS Mincho";
}
}
}
The second solution would be to change the East Asian font value
only for the style definitions (and not for the document default paragraph and run properties):
using (WordprocessingDocument myDocument = WordprocessingDocument.Open(#"C:\users\" + Environment.UserName + #"\Desktop\eastAsiaFix.dotm", true))
{
StyleDefinitionsPart stylesPart = myDocument.MainDocumentPart.StyleDefinitionsPart;
if (stylesPart == null)
{
Console.Out.WriteLine("No styles part found.");
return;
}
foreach(var style in stylesPart.Styles.Descendants<Style>())
{
foreach(var rf in style.Descendants<RunFonts>())
{
if(rf.EastAsia != null)
{
Console.Out.WriteLine("Found: {0}", rf.EastAsia.Value);
rf.EastAsia.Value = "MS Mincho";
}
}
}
}
Related
I have console app which i am trying to automate , there is manual process to remove headers and footer tags form .trg file . Can anyone suggest how to remove headers and footers using c sharp.
Header looks like this.
<Batch remotefolder="\\srv-dg-procl13\nexdox\nxtil04\process\200863-142325x-mkts\output\archive\absamples_pims_pdf\" grid="200863-142325X-MKTS" streamID="ABSAMPLES_PIMS_PDF" delivertobox="False">
<Application application="NXTIL04" name="Mifid 10 percent drop Notification " output="ABSAMPLES_PIMS_PDF">
<Indexes>
<Index name="Reference" description="Reference" type="StringDefinition" visible="True" />
</Indexes>
</Application>
footer looks like this .
</Batch>
This is what i am trying to do but not working .
private void RemoveHeader(string Xlfile)
{
XmlDocument doc = new XmlDocument();
doc.Load(Xlfile);
foreach (XmlNode node in doc.SelectSingleNode("Batch"))
{
doc.RemoveAll();
}
}
XPath is your friend here.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace testconsole
{
class Program
{
public static string strFileName = "c:\\temp\\test.xml";
static void Main(string[] args) {
XmlDocument xml = new XmlDocument();
xml.Load(strFileName);
XmlElement ndMatch = (XmlElement)xml.SelectSingleNode("//Application");
if (ndMatch != null) {
XmlDocument xmlNew = new XmlDocument();
xmlNew.LoadXml(ndMatch.OuterXml);
xmlNew.Save(strFileName + ".new");
} else {
Console.Write("Cannot load " + strFileName);
}
}
}
}
I'm trying to programatically fill in some ContentControls inside a MS Word document with C#.
So far I've been able to open the document and find all the controls, but they come back as generic ContentControl objects. Inspecting them with a debugger just reveals a generic System.__ComObject.
From the docs I can see that some of the controls should have a .Text property, but I cannot figure out how to access it.
I can determine the type of the control using the switch statement you see below, but it doesn't really help me -- I don't know what class to cast the object to (if that's even what I'm supposed to do).
There is a class called PlainTextContentControl but it exists in Microsoft.Office.Tools.Word, but the Application and Document and ContentControl live under Microsoft.Office.Interop.Word and these do not play nicely together.
So I'm lost. How do I access the Text property? Here's what I've got:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using Microsoft.Office.Interop.Word;
//using Microsoft.Office.Interop.Word;
using Microsoft.Office.Tools.Word;
using ContentControl = Microsoft.Office.Interop.Word.ContentControl;
using Document = Microsoft.Office.Interop.Word.Document;
namespace ConsoleApplication1
{
internal class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Opening Word Application...");
var app = new Application();
try
{
Console.WriteLine("Loading document...");
var doc = app.Documents.Open(
#"C:\blahblah\template3.docx");
Console.WriteLine("Finding controls...");
var controls = GetAllContentControls(doc);
foreach (var control in controls)
{
Console.WriteLine(control.Tag);
switch (control.Type)
{
case WdContentControlType.wdContentControlText:
var pt = control as PlainTextContentControl;
Console.WriteLine("hit"); // pt is null
break;
}
}
doc.Close();
}
finally
{
app.Quit();
}
}
public static List<ContentControl> GetAllContentControls(Document wordDocument)
{
var ccList = new List<ContentControl>();
foreach (Range range in wordDocument.StoryRanges)
{
var rangeStory = range;
do
{
try
{
foreach (ContentControl cc in rangeStory.ContentControls)
{
ccList.Add(cc);
}
}
catch (COMException)
{
}
rangeStory = rangeStory.NextStoryRange;
} while (rangeStory != null);
}
return ccList;
}
}
}
I should note that I'm using JetBrains Rider instead of Visual Studio. If this is impossible to do with Rider for some reason, I can probably obtain a copy of VS.
You can just use the code resemble the following:
switch (control.Type)
{
case WdContentControlType.wdContentControlText:
var text = control.Range.Text;
//var pt = control as PlainTextContentControl;// pt is null
Console.WriteLine(text);
break;
case WdContentControlType.wdContentControlRichText:
var richText = control.Range.Text;
//var pt1 = control as PlainTextContentControl;// pt1 is null
Console.WriteLine(richText);
break;
}
This code is replacing the text with an image but its placing the multiple copies of an image and placing them in the beginning of the document. I want the image to be placed at the same position where text was present. My find text is available in the table cell. Is it due to that?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using word = Microsoft.Office.Interop.Word;
using System.Runtime.InteropServices;
//using System.Drawing;
namespace WritingIntoDocx
{
[ComVisible(true)]
public interface IMyClass
{
void DocumentDigitalSign(string filep,string findt,string replacet);
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class Program : IMyClass
{
public void DocumentDigitalSign(string filep, string findt, string imagepath)
{
string filepath = filep;
string Findtext = findt;
word.Application app = new word.Application();
word.Document doc = app.Documents.Open(filepath);
word.Range myStoryRange = doc.Range();
//First search the main document using the Selection
word.Find myFind = myStoryRange.Find;
myFind.Text = Findtext; myFind.Replacement.Application.Selection.InlineShapes.AddPicture(imagepath);
myFind.Forward = true;
myFind.Wrap = word.WdFindWrap.wdFindContinue;
myFind.Format = false;
myFind.MatchCase = false;
myFind.MatchWholeWord = false;
myFind.MatchWildcards = false;
myFind.MatchSoundsLike = false;
myFind.MatchAllWordForms = false;
myFind.Execute(Replace: word.WdReplace.wdReplaceAll);
//'Now search all other stories using Ranges
foreach (word.Range otherStoryRange in doc.StoryRanges)
{
if (otherStoryRange.StoryType != word.WdStoryType.wdMainTextStory)
{
word.Find myOtherFind = otherStoryRange.Find;
myOtherFind.Text = Findtext; myOtherFind.Replacement.Application.Selection.InlineShapes.AddPicture(imagepath);
myOtherFind.Wrap = word.WdFindWrap.wdFindContinue;
myOtherFind.Execute(Replace: word.WdReplace.wdReplaceAll);
}
// 'Now search all next stories of other stories (doc.storyRanges dont seem to cascades in sub story)
word.Range nextStoryRange = otherStoryRange.NextStoryRange;
while (nextStoryRange != null)
{
word.Find myNextStoryFind = nextStoryRange.Find;
myNextStoryFind.Text = Findtext;
myNextStoryFind.Replacement.Application.Selection.InlineShapes.AddPicture(imagepath);
myNextStoryFind.Wrap = word.WdFindWrap.wdFindContinue;
myNextStoryFind.Execute(Replace: word.WdReplace.wdReplaceAll);
nextStoryRange = nextStoryRange.NextStoryRange;
}
}
app.Documents.Save();
app.Documents.Close();
}
}
}
Replacement.Application is a reference to the application object. When you call AddPicture() on that, the picture is immediately inserted at the current position before the find operation is even executed.
I see two possibilities:
Load the picture, place it into the Windows clipboard and then execute the find operation specifying "^c" as replacement text. Word will replace "^c" with the current content of the clipboard. This is what the documentation says:
ReplaceWith
Type: System.Object
Optional Object.
The replacement text. To delete the text specified by the Find argument, use an empty string (""). You specify special characters and advanced search criteria just as you do for the Find argument. To specify a graphic object or other non-text item as the replacement, move the item to the Clipboard and specify "^c" for ReplaceWith.
Do not use wdReplaceAll, but wdReplaceNone, so that the find operation itself does not do any replacing. But you then have the chance to insert your content at the place found. Do that in a loop until no more occurrence is found.
I have a Visio ER diagram and want to read the database properties (Columns, Primary, Foreign key, data type) information from an Entity. Also want to find the parent and child tables associated. How can I programmatically achieve it using C#?
I am using Interop Visio library and can read the pages and shape from ER diagram but don't know which functions or methods in Visio interop will let me get properties information from a Shape.
Below is the code I am using and I am not getting any property using it. My ER diagram have just two entities a Parent and a Child table.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Office.Interop.Visio;
namespace Visio_POC
{
public partial class Load_Visio : Form
{
static string strProperties = "";
public Load_Visio()
{
InitializeComponent();
string strFileName = "\\Visio_POC\\POC_Visio.vsd";
Microsoft.Office.Interop.Visio.Application vsApp = new Microsoft.Office.Interop.Visio.Application();
Microsoft.Office.Interop.Visio.Document docVisio = vsApp.Documents.Add(strFileName);
Page pgVisio = docVisio.Pages[1];
Shapes shpVisio = pgVisio.Shapes;
int intCnt = shpVisio.Count;
string[] strShapeText = new string[intCnt];
printProperties(pgVisio.Shapes);
txtProperties.Text = strProperties;
}
public static void printProperties(Shapes shapes)
{
// Look at each shape in the collection.
foreach (Shape shape in shapes)
{
// Use this index to look at each row in the properties
// section.
short iRow = (short) VisRowIndices.visRowFirst;
// While there are stil rows to look at.
while (shape.get_CellsSRCExists(
(short) VisSectionIndices.visSectionProp,
iRow,
(short) VisCellIndices.visCustPropsValue,
(short) 0) != 0)
{
// Get the label and value of the current property.
string label = shape.get_CellsSRC(
(short) VisSectionIndices.visSectionProp,
iRow,
(short) VisCellIndices.visCustPropsLabel
).get_ResultStr(VisUnitCodes.visNoCast);
string value = shape.get_CellsSRC(
(short) VisSectionIndices.visSectionProp,
iRow,
(short) VisCellIndices.visCustPropsValue
).get_ResultStr(VisUnitCodes.visNoCast);
// Print the results.
//Console.WriteLine(string.Format(
// "Shape={0} Label={1} Value={2}",
// shape.Name, label, value));
strProperties = strProperties + shape.Name + " - " + label + " - " + value;
// Move to the next row in the properties section.
iRow++;
}
// Now look at child shapes in the collection.
if (shape.Master == null && shape.Shapes.Count > 0)
printProperties(shape.Shapes);
}
}
}
}
The database reverse engineering is a closed solution. There was a book "Database Modeling" by Terry Halpin which covered this. Alternatively you could peruse my article at http://blog.bvisual.net/2014/03/26/creating-a-schema-from-visio-external-data-record-sets/ for an idea of how you could do it yourself.
I googled and found the solution at MSDN.
// Compose a string that consists of three lines.
string lines = "First line.\r\nSecond line.\r\nThird line.";
// Write the string to a file.
System.IO.StreamWriter file = new System.IO.StreamWriter("c:\\test.txt");
file.WriteLine(lines);
file.Close();
How to extend the lines to complex content which including some natural C# code lines.
eg. I want to write the information below to my test.cs file.
Why?
I am parsing a XML schema with C# Console Application. And i want to generate the Console Result to a .cs file during the compiler time.
using System;
using System.Collections.Generic;
using System.Text;
namespace CommonDef
{
public class CCODEData
{
public int iCodeId;
public string sCode;
public CODEDType cType;
public int iOccures;
}
[Description("CodeType for XML schema.")]
public enum CODEDType
{
cString = 1,
cInt = 2,
cBoolean = 3,
}
thank you.
If your source code is hardcoded as in your sample, you could use a C# literal string:
string lines =
#"using System;
using System.Collections.Generic;
using System.Text;
namespace CommonDef
..."
Anyway in such cases it is a better idea (more readable and maintainable) to have the whole text contents into a text file as an embedded resource in your assembly, then read it using GetManifestResourceStream.
(I'm assuming you're trying to build up the result programmatically - if you genuinely have hard-coded data, you could use Konamiman's approach; I agree that using an embedded resource file would be better than a huge verbatim string literal.)
In your case I would suggest not trying to build up the whole file into a single string. Instead, use WriteLine repeatedly:
using (TextWriter writer = File.CreateText("foo.cs"))
{
foreach (string usingDirective in usingDirectives)
{
writer.WriteLine("using {0};", usingDirective);
}
writer.WriteLine();
writer.WriteLine("namespace {0}", targetNamespace);
// etc
}
You may wish to write a helper type to allow simple indentation etc.
If these suggestions don't help, please give more details of your situation.
I know an answer has already been accepted but why not use an XSLT applied to the XML instead? this would mean that you could easily generate c#, vb.net, .net without having to recompile the app.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FileHandling
{
class Class1
{
static void Main()
{
Console.WriteLine("Enter data");
ConsoleKeyInfo k;
//Console.WriteLine(k.KeyChar + ", " + k.Key + ", " + k.Modifiers );
string str="";
char ch;
while (true)
{
k = Console.ReadKey();
if ((k.Modifiers == ConsoleModifiers.Control) && (k.KeyChar == 23))
{
Console.WriteLine("\b");
break;
}
if (k.Key == ConsoleKey.Enter)
{
Console.WriteLine("");
str += "\n";
}
ch = Convert.ToChar(k.KeyChar);
str += ch.ToString();
}
Console.WriteLine(str);
Console.Read();
}
}
}