Insert text to Word document - c#

I would like to insert text to Word document, in a specified format, using Interop.Word:
Something like this :
wordDoc.InsertText("Text \n", "Arial");
or
wordDoc.InsertText("Text \n", "Bold");
Is it possible?

There is no direct method like this AFAIK. However, you can write a wrapper over Word Interop and do it. Internally inside your InsertText() method you will have to do the following.
1: Use the Text property of a Range object to insert text in a document.
object start = 0;
object end = 12;
Word.Range rng = this.Range(ref start, ref end);
rng.Text = "New Text";
rng.Select();
2: Format text using a document-level customization.
// Set the Range to the first paragraph.
Word.Range rng = this.Paragraphs[1].Range;
// Change the formatting.
rng.Font.Size = 14;
rng.Font.Name = "Arial";
rng.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
rng.Select();
For further details please see this and this which I have used sometime back with good results.
Hope this helps.

Related

MS Word - Insert Text in worddocument after specified text

found several matches to my request, but not for word, so I open a new thread.
I got a word document. After a specified text, I want to insert some lines.
My code looks like that:
public static class Program
{
static void Main(string[] args)
{
string Filename = #"D:\...\MasterDoc.docx";
string SearchFor = "Search this text and insert after it";
string DocText = string.Empty;
int InsertIndex = 0;
//Run or attach MS Word
Microsoft.Office.Interop.Word.Application wrdApp = RunOrAttachWordApplication();
//Open masterfile
Microsoft.Office.Interop.Word.Document doc = wrdApp.Documents.Open(Filename);
//Get complete range
Microsoft.Office.Interop.Word.Range rng = doc.Range();
//Get document text
DocText = rng.Text;
//Search indes to insert text
InsertIndex = DocText.IndexOf(SearchFor) + SearchFor.Length;
//Define range at location for text pasting
rng = doc.Range(InsertIndex, InsertIndex + 1);
//Write 'Test...' on specified location
rng.InsertAfter("Test...");
//Close document
doc.Close(); /*Right here I got a breakpoint and watch the result, so I do not need to save the document here*/
//Close application
wrdApp.Application.Quit();
wrdApp.Quit();
wrdApp = null;
System.GC.Collect();
System.Console.WriteLine("Ende...");
System.Console.ReadKey();
}
public static Microsoft.Office.Interop.Word.Application RunOrAttachWordApplication()
{
if(System.Diagnostics.Process.GetProcessesByName("Word").Length > 0)
{
return System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application") as Microsoft.Office.Interop.Word.Application;
}
else
{
return new Microsoft.Office.Interop.Word.Application();
}
}
}
Well, it works - but not correctly. The text is inserted about 50 digits before the location, I want.
Does anybody know, how to fix that or I could imagine, that there is a much better methode to do that. I cannot modify the Masterdocument as it is recreated everytime by another, external program.
Thank you very much and regards,
Jan
I find the Find.Execute method much cleaner and shorter for adding/replacing text in the Word VSTO.
doc.Range().Find.Execute(FindText: SearchFor, Replace: WdReplace.wdReplaceOne, ReplaceWith: SearchFor + " Test...");
It has many options, but for replacing the text I used:
FindText - the text to find.
Replace - how many replacements to make. [WdReplace][2]
ReplaceWith - the text.
I suspect that there is some metadata at the beginning of the file which is being ignored when you lookup the required index here:
DocText.IndexOf(SearchFor) + SearchFor.Length;
You can add the discrepancy to the insert, given that the amount is constant for all files:
//Search indes to insert text
InsertIndex = DocText.IndexOf(SearchFor) + SearchFor.Length + 50;
However, the most eloquent solution would be to stop using rng.InsertAfter and instead set rng.Text like this:
//Get document text
DocText = rng.Text;
//Search indes to insert text
InsertIndex = DocText.IndexOf(SearchFor) + SearchFor.Length;
//Update the text
DocText = DocText.Substring(0, InsertIndex) + "Test..." + DocText.Substring(InsertIndex);
// Set the new text
rng.Text = DocText;
Will unfortunatelly, the solution of EyIM does not work, as the textlength increased and its limited to 255 characters. Any other solutions? I really want to insert text, as there is some format in the document and I need to keep that.

How to add bookmark in word document header programmatically?

I have done bookmark creation in word document. but, In main text part not in header and footer part. Now, I want to create bookmark in Primary Header Section.
Actually, I am trying to update text of bookmark at run time. But, whenever I change the text of bookmark it get removed. So, I have to create it again programmatically.
This is my code to replace the text of word document bookmark.
if (doc.Bookmarks.Exists(_bookMarkName))
{
object oBookMark = _bookMarkName;
//Getting Bookmark Object
Microsoft.Office.Interop.Word.Bookmark bookmark = doc.Bookmarks.get_Item(ref oBookMark);
//calculating range to create bookmark.
object start = bookmark.Range.Start;
object end = bookmark.Range.Start + _value.Length;
//After replacing this text, bookmark will be removed from the document. So, we have to creat it again.
bookmark.Range.Text = _value;
//Creating range from new values.
object range = doc.Range(ref start, ref end);
doc.Bookmarks.Add(_bookMarkName, ref range); //Adding new bookmark with new range
}
So, what is the problem in this code is the StoryType property of bookmark object will be Microsoft.Office.Interop.Word.WdStoryType.wdPrimaryHeaderStory before replacing bookmark text. but, after creating new bookmark the property StoryType will be taken as Microsoft.Office.Interop.Word.WdStoryType.wdMainTextStory instead of Microsoft.Office.Interop.Word.WdStoryType.wdPrimaryHeaderStory. So, How do I change that property or assign that property when bookmark is being created. The property StoryType is ReadOnly. So, I could not assign it after creating bookmark.
`
The problem is basically creating the new range using the doc as the starting point. SInce the Range object doesn't have a Range method, I think you would have to get the relevant StoryRange from the bookmark's range, then use GetRange to get a range in the appropriate story. I haven't checked...
...because that should not be necessary, assuming that you want the replacement bookmark to "cover" the text that you just inserted, because you should be able to do something more like this, assuming you can retranslate this VBA syntax back into C#
Dim bm As Word.Bookmark
Dim bookMarkName As String
Dim doc As Word.Document
Dim newValue As String
Dim rng As Word.Range
'.
'.
If doc.Bookmarks.Exists(bookMarkName) Then
' Could do the following two statements in one
Set bm = doc.Bookmarks(bookMarkName)
Set rng = bm.Range
rng.Text = newValue
doc.Bookmarks.Add bookMarkName, rng
Set rng = Nothing
Set bm = Nothing
End If

Insert formatted text to Word document

I insert text to a Word document. This is done by selection.TypeText("text");
I would like to insert formatted text to a Word document, something like:
public override void InsertText(string content, string format)
{
selection.Style = format; //something like this
selection.Font.Name = "Heading 1"; //or like this
selection.TypeText(content);
}
Any ideas?
For a Word Document-Level Customization where Microsoft.Office.Interop.Word is referenced, this works:
this.ActiveWindow.Selection.Range.Font.Name = "Arial";
this.ActiveWindow.Selection.Range.Font.Size = 36;
You can also assign the range of a selection to a range variable and then apply formats to the variable as in:
Word.Range myRange = this.ActiveWindow.Selection.Range;
myRange.Font.Size = 18;
myRange.Font.Name = "Arial";
EDIT (Response to OP's question in comments)
To apply a Heading style to the selected text assign one of Word's WdBuiltinStyle enumeration members:
object headingStyle = Word.WdBuiltinStyle.wdStyleHeading1;
this.ActiveWindow.Selection.Range.set_Style(ref headingStyle);
To view the full list of enumeration members, see this:
MSDN: WdBuiltinStyle enumeration

VSTO format word-footer to be left-bound

im need to implement a way to one-click add a footer to a word document consisting of one line.
The first part needs to be the absolute Path to the document and it has to be left-bound. In addition to this, there has to be the actual page number aligned to the right.
This wasn't a problem on Excel; there I could use LeftFooter, CenterFooter, RightFooter.
On Word however there are no such properties to access.
edit: I found a semi-working solution which has some bugs in it and isn't properly designed because I could not find a proper way yet.
Word.Document doc = Globals.ThisAddIn.Application.ActiveDocument;
foreach (Word.Section wordSection in doc.Sections)
{
Word.Range PageNumberRange = wordSection.Range;
PageNumberRange.Fields.Add(PageNumberRange, Word.WdFieldType.wdFieldEmpty ,"PAGE Arabic ", true);
Word.Range footer = wordSection.Footers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
footer.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter;
footer.Tables.Add(footer, 1, 3);
Word.Table tbl = footer.Tables[1];
tbl.Cell(1, 1).Range.Text = doc.FullName;
tbl.Cell(1, 3).Range.Text = PageNumberRange.Text;
/**/
footer.Font.ColorIndex = Word.WdColorIndex.wdBlack;
footer.Font.Size = 6;
PageNumberRange.Text = "";
The problems with this one are: It never overwrites the exisiting footer. If it writes "document1 ... 1" and you click on it again, because you saved your document, it doenst change the footer. Furthermore: If you have multiple pages, every page except page 1 gets deleted.
I never imagined it could be so hard, to implement such an easy task.
An alternative approach using styles
Document doc = this.application.ActiveDocument;
Section wordSection = doc.Sections[1];
Range footer = wordSection.Footers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
footer.Fields.Add(footer, WdFieldType.wdFieldEmpty, #"PAGE \* ARABIC", true);
footer.Collapse(WdCollapseDirection.wdCollapseStart);
footer.InsertBefore("\t \t");
footer.InsertBefore(doc.FullName);
footer.Font.Name = "Arial";

How to insert blank page at the begining of word 2003 document

In fact, I can insert a new blank page at the beginning of a Word 2003 document and some text.
However the problem is the new blank page will get the format or style from the next page.
For example:
The original document with bullet point:
a
b
c
d
 
After editing with the C# code below:
Hello world
-----
a
b
c
d
I want to insert a new blank page without any styles or formatting.
How can I do this in C#?
Here is the existing code that I'mu sing to try and insert a blank page with some text:
var app = new Application();
app.Visible = false;
app.DisplayAlerts = WdAlertLevel.wdAlertsNone;
var doc = app.Documents.Open(#"C:\test.doc");
object what = WdGoToItem.wdGoToLine;
object which = WdGoToDirection.wdGoToFirst;
app.Selection.GoTo(ref gotoPage, ref gotoNext, ref gotoCount, ref gotoName);
//Insert a blank page
app.Selection.InsertNewPage();
object start = 0;
object end = 0;
var range = doc.Range(ref start, ref end);
range.Font.Size = 10;
range.Text = "Hello\n World";
doc.Save();
doc.Close();
app.Quit();
Thanks very much.
I would also appreciate if you could suggest how to insert text with new line sign as "\n" doesn't work.
I am not quit sure whether this will work for the Word 2003. I've tried this for Word 2010. The idea is to reset style of the Paragraph. Considering your code:
//Insert a blank
app.Selection.InsertNewPage();
Word.Paragraph par = doc.Paragraphs[1];
par.Reset();
Take a look on this page. Hopefully this will help you.
Considering line break, I would suggest to try '\r' or '\r\n' symbols. Or as Pat has proposed, you can try Environment.NewLine. In Word 2010 your code works also fine, I mean with \n.
I overcome this problem with merge two file one for blank and one is original.
This is helpful article to solve this problem.
How To: Merge Multiple Microsoft Word Documents in C#
Try to insert the Page Break by inserting symbols "\f\r". And then set the Style of the first paragraph like "Normal".
For example:
Range docRange = doc.Range();
docRange.Text = docRange.Text.Insert(0, "\f\r");
docRange.Paragraphs.First.set_Style(WdBuiltinStyle.wdStyleNormal);

Categories