I have to make some Word Integration as part of an exam project. My problem is that I am rather new to Microsoft Word integration in C#. I have the Assemblies I need, and I got everything set-up ready to write code pretty much. The document will be generated from scratch.
But I am just starring at the blinking cursor, not really knowing how to start.
I have to take a StringBuilder (which should hold stuff like escape characters for new lines, perhaps italic bold, etc kind of formatting as well.) The StringBuilder will be given from another part of the application written by my friend.
Would you suggest that this is delivered in another form than a StringBuilder Object?
And where should I start with all this? It's a bit overwhelming.
Thanks
Try this
you need to add Microsoft.Office.Interop.Word reference
Word._Application oWord;
Word._Document oDoc;
object oMissing = Type.Missing;
oWord = new Word.Application();
oWord.Visible = true;
//Add Blank sheet to Word App
oDoc = oWord.Documents.Add(ref oMissing, ref oMissing, ref oMissing, ref oMissing);
oWord.Selection.TypeText("Write your text here");
//FOrmatting your text
oWord.Selection.Font.Size = 8;
oWord.Selection.Font.Name = "Zurich BT";
oWord.Selection.Font.Italic = 1
oWord.Selection.Font.Bold = 1
oDoc.Content.Application.ActiveWindow.ActivePane.View.SeekView = //Havent tested the
//header and footer part
Word.WdSeekView.wdSeekCurrentPageFooter;
oDoc.Content.Application.Selection.TypeText(“Martens”);
I guess this might be what you are looking for
Related
We have an existing legacy system where I'm able to download existing templates, update them and save them as documents with my edits. Here is a portion of the code.
#region Open existing Template and write something to it.
object missing = Type.Missing;
Word.Application app = new Word.Application();
Word.Document doc = app.Documents.Open(#"C:\\test395310.dot", ref missing, true);
doc.Activate();
doc.Variables["CASE PLAN_PLAN_STATUS"].Value = "asdf1";
doc.Variables["CASE PLAN_PROGRAM"].Value = "asdf2";
doc.Fields.Update();
#endregion
Using similar logic I'm attempting to create a new word template with 2 variables.
private static void CreateTemplate()
{
//have it open word and create a template with fields from gen
object missing = Type.Missing;
Word.Application app = new Word.Application();
Word.Document doc = app.Documents.Add(ref missing, ref missing, true);
doc.Activate();
doc.Variables.Add("CASE PLAN_PLAN_STATUS", "XXXXX");
doc.Variables.Add("ANOTHER ONE", "XXXX");
doc.Fields.Update();
doc.SaveAs2(#"C:\\newTemplate.dot");
doc.Close();
app.Quit();
}
The document is getting created, however in word I cannot find either variable. My goal is to open word and placement in the template with formatting. ie
Plan Status: <<CASE PLAN_PLAN_STATUS>>
If I click insert/Explore Quick Parts/field, I can see various options, but my two variables aren't there. Anyone know where else to look? Or a better approach?
Within your template, you can use DocVariable fields.
https://support.microsoft.com/en-us/office/field-codes-docvariable-field-32a81e22-c5c1-4b16-8097-f0de851db67c?ui=en-US&rs=en-US&ad=US
It would look like { DocVariable Case_Plan_Plan_Status } with field codes revealed.
Unlike Document Properties, Document Variables can only be created, modified, or deleted using vba.
There are no built-in Document Variables. There is no tool built into the user interface for seeing what is available among variables.
I do know of several good Add-Ins for manipulating them in the user interface.
One is Chris Woodman's old Keyboard Shortcut Organizer.
http://addbalance.com/word/download.htm#ChrisWoodman
This one lets you view, create, edit and delete variables from within Word but does not create a DocVariable field, leaving that for you to do.
Another is Graham Mayor's or Greg Maxey's utility.
http://gregmaxey.com/word_tip_pages/cc_var_bm_doc_prop_tools_addin.html
or
http://www.gmayor.com/BookmarkandVariableEditor.htm
Both of these last two can add a DocVariable Field to your document after you select the variable from a list.
I want to print out a Word document without saving it in advance. Is this possible?
//I created an instance for word app
Microsoft.Office.Interop.Word.Application winword = new Microsoft.Office.Interop.Word.Application();
//I created a Word document (including pararaphs and tables):
Microsoft.Office.Interop.Word.Document document = winword.Documents.Add(ref missing, ref missing, ref missing, ref missing);
//I can print the document, if I save it before. But I want to print it without saving the word document.
document.SaveAs2(#"C:\User\\Desktop\Test");
document.PrintOut()
//Export of the document as pdf-file.
document.ExportAsFixedFormat(label24.Text + "Document" + textBox13.Text, WdExportFormat.wdExportFormatPDF, true);
If the problem is that the document is closing before the print job has completed, then the best approach is to turn off background printing, at least for the duration of code execution.
winword.Options.PrintBackground = false;
Background printing was introduced in order to allow the user to continue working while a print job was processing. This is fine for the user, but a problem for code such as that in the question.
I have a word document which contains multiple pages and i want to copy some pages into new word document using OpenXml SDK. I did some web search and got below code which reads entire document and copies into new one
string documentURL = filelocation;
byte[] docAsArray = File.ReadAllBytes(documentURL);
using (MemoryStream stream = new MemoryStream())
{
stream.Write(docAsArray, 0, docAsArray.Length); // THIS performs doc copy
using (DocumentFormat.OpenXml.Packaging.WordprocessingDocument doc = DocumentFormat.OpenXml.Packaging.WordprocessingDocument.Open(stream, true))
{
// perform content control substitution here, making sure to call .Save()
// on any documents Part's changed.
}
File.WriteAllBytes(outputSplitDocpath, stream.ToArray());
}
Now, in the above code how can i read just specific pages and copy into new one? Please help with suggestions. Thanks
Unless a manual page break has been used to generate every page in the document, what you want to do is not possible.
Automatic page breaks are generated by Word, at run-time, when the document is open in the Word application. The actual placement of a page break is completely dynamic, based on the editing being done and is recalculated "all the time" during editing.
This information is not reliably saved in the document when the document is closed. One reason for this is because the document could lay out differently when opened on a different machine, or when a different printer (driver) is selected.
So it's not possible to work with individual pages using the Office Open XML file format unless there's some way each page can be recognized, such as a manual page break.
Use Microsoft.Office.Interop.Word.Application word = new Microsoft.Office.Interop.Word.Application();
instead of OpenXML
//dummy value to satisfy params
object oMissing = System.Reflection.Missing.Value;
//copy specific page/s
object what = WdGoToItem.wdGoToPage;
object which = WdGoToDirection.wdGoToFirst;
object count1 = 1;
Range startRange = word.Selection.GoTo(ref what, ref which, ref count1, ref oMissing);
object count2 = (int)count + 1;
Range endRange = word.Selection.GoTo(ref what, ref which, ref count2, ref oMissing);
endRange.SetRange(startRange.Start, endRange.End - 1);
endRange.Select();
word.Selection.Copy();
//save...
I'm currently facing a problem regarding the MailMerge functionality of MS Word.
I had to rewrite an old VBA Application into C#. I'm practically done with that. New Application works fine.
Except for one PopUp that I cannot get rid of.
So I have been looking around on the web for the past 2 days because our clients don't want that pop up as it hasn't been there in the old application.
However I couldn't find a proper solution for this. Except a few people mentioning that probably the Connection string is incorrect. But I found no resources telling me how it should look in the C# code
This it how it looks in the old application:
Word.ActiveDocument.MailMerge.OpenDataSource Name:=strSourceDoc, ConfirmConversions:=False, _
ReadOnly:=False, LinkToSource:=True, AddToRecentFiles:=False, PasswordDocument:="", _
PasswordTemplate:="", WritePasswordDocument:="", WritePasswordTemplate:="", _
Revert:=False, Format:=wdOpenFormatAuto, Connection:= _
"Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source=" & strSourceDoc & ";Mode=Read;Extended Properties=""HDR=YES;IMEX=1;"";Jet OLEDB:System database="""";" _
, SQLStatement:="SELECT * FROM `Tabelle1$`", SQLStatement1:="", SubType:= _
wdMergeSubTypeAccess
I obviously tried already to take that connection key and use it in my code. But it does not prevent that pop up. I also tried playing around with the subtype. But it either doesn't change anything or throws a format exception.
This is whats working in C#:
mailApp.ActiveDocument.MailMerge.OpenDataSource(processedPath + file, true, false, true,
true, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing,
"Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source=" +
processedPath + file + ";Mode=Read;",
"SELECT * FROM 'Tabelle1$'",
ref oMissing, ref oMissing, ref oMissing,
Word.WdMergeSubType.wdMergeSubTypeAccess);
How can I change the connection string to prevent that popup from showing?
So I found a solution, that is somehow working.
The actual problem (at least from what I tested) is the file extension not the connection string. I was using .xlsx files, as my source documents. But as soon as I tested with some xls Files the popup disapeared.
I just took a "google session" to find out the differences between xls and xlsx.
So I could change my code to work with xls Files only. Issue solved. But still an unpleasing solution for me tbh.
If you'd like to test around a little to maybe get it working with xlsx. Here is some code to test with (just bind it on a button click in winforms or something)
class PerformMailMerge
{
Word.Application mailApp;
Object oMissing = System.Reflection.Missing.Value;
Object oFalse = false;
string _path = #"Your Path to Excel File";
string savePath = #"Your Path to Word Document";
public void mailMerge2()
{
mailApp = new Word.Application();
mailApp.Visible = false;
mailApp.Documents.Add();
mailApp.ActiveDocument.MailMerge.MainDocumentType = Word.WdMailMergeMainDocType.wdMailingLabels;
//OpenDataSource:
mailApp.ActiveDocument.MailMerge.OpenDataSource(_path,
Word.WdOpenFormat.wdOpenFormatAllWordTemplates, true, true, true,
ref oMissing, ref oMissing, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, "TABLE Tabelle1$", "SELECT * FROM `Tabelle1$",
ref oMissing, ref oMissing,
Word.WdMergeSubType.wdMergeSubTypeWord2000);
mailApp.ActiveDocument.SaveAs2(savePath);
mailApp.ActiveDocument.Close();
mailApp.Quit();
}
}
EDIT:
So in case anyone will stumble upon this again. I found a solution to the problem. The solution is NOT specifying a WdMergeSubType. This allows reading from xlsx files and still doesn't show the popup!
I've found loads of useful documentation around creating an instance of a word doc, inserting all manner of text and formatting but cannot find anywhere something to save a document that hasnt already been created and opened programmatically.
Essentially I want to create a docx file and fill it with text from a rich text box. Using code Ive found at How to Insert text in the end of the document I am able to achieve this if I first create a document. But despite suggestions of using _document.SaveAs() (which doesnt exist - version diff i guess) or .Save() supposedly prompting with a SaveAs dialogue if the file doesnt already exist, I always get a type mismatch error. So this is the working code if i pre-create the file to use:
OpenFileDialog SDO = new OpenFileDialog();
SDO.ShowDialog();
Microsoft.Office.Interop.Word._Application oWord;
object oMissing = Type.Missing;
oWord = new Microsoft.Office.Interop.Word.Application();
oWord.Visible = false;
oWord.Documents.Open(SDO.FileName);
oWord.Selection.TypeText(richTextBox1.Text);
oWord.ActiveDocument.Save();
oWord.Quit();
Now one would assume that removing the lines for the OpenFileDialogue Documents.Open would go some way to saving a new file created in C#, however even with:
Microsoft.Office.Interop.Word._Application oWord;
object oMissing = Type.Missing;
oWord = new Microsoft.Office.Interop.Word.Application();
oWord.Visible = false;
SaveFileDialog SD = new SaveFileDialog();
SD.Filter = "Word File |*.docx";
SD.Title = "Save File";
SD.ShowDialog();
oWord.Documents.Save(SD.FileName,WdNewDocumentType.wdNewXMLDocument);
oWord.Selection.TypeText(richTextBox1.Text);
oWord.ActiveDocument.Save();
oWord.Quit();
Other examples ive seen open the document so that you can save it yourself but i need it saving without any human intervention other than choosing a filename.
Any help appreciated, also the option of third party dlls like spire and gem are precluded so not an option :(
If anyone has a simple example of creating and saving a word doc that didnt exist before the program ran id be much obliged.
The Microsoft MSDN documentation has tons of useful guides and examples.
You are going to want to include:
using Word = Microsoft.Office.Interop.Word;
using Microsoft.Office.Tools.Word;
Then declare your application:
Word.Application app = new Word.Application();
Declare your new document:
Word.Document doc = app.Documents.Add();
Add text to your documnet
There are two ways to save these documents:
Programmatically
Using a save file dialog box
This is the way I do it.
app = new Word.Application();
object oMissing = System.Reflection.Missing.Value;
Word._Document oDoc = app.Documents.Add(ref oMissing, ref oMissing,
ref oMissing, ref oMissing);
.....
app.ActiveDocument.SaveAs2(fileName);
Where filename is my desired file name. When I was originally doing this, I discovered that there were a lot of undocumented (and therefore unsupported) functions. SaveAs2 is one of them! But it does work.