I read it some post referring to Populate word documents, but I need to populate a word document (Office 2007) using C#. For example i want to have a word document with a label [NAME], use that label in C# to put my value, and do all this in a ASP.NET MVC3 controller. Any idea?
You could use the OpenXML SDK provided by Microsoft to manipulate Word documents. And here's a nice article (it's actually the third of a series of 3 articles) with a couple of examples.
You can do like this :
- Introduce "signets" into your Word document template
- Work on a copy of your word template
- Modify signets values from c# code and save or print your file.
Be carefull with releasing correctly your word process if you treat several documents in your application :)
OP's solution extracted from the question:
The solution i found is this:
static void Main(string[] args)
{
Console.WriteLine("Starting up Word template updater ...");
//get path to template and instance output
string docTemplatePath = #"C:\Users\user\Desktop\Doc Offices XML\earth.docx";
string docOutputPath = #"C:\Users\user\Desktop\Doc Offices XML\earth_Instance.docx";
//create copy of template so that we don't overwrite it
File.Copy(docTemplatePath, docOutputPath);
Console.WriteLine("Created copy of template ...");
//stand up object that reads the Word doc package
using (WordprocessingDocument doc = WordprocessingDocument.Open(docOutputPath, true))
{
//create XML string matching custom XML part
string newXml = "<root>" +
"<Earth>Outer Space</Earth>" +
"</root>";
MainDocumentPart main = doc.MainDocumentPart;
main.DeleteParts<CustomXmlPart>(main.CustomXmlParts);
//MainDocumentPart mainPart = doc.AddMainDocumentPart();
//add and write new XML part
CustomXmlPart customXml = main.AddCustomXmlPart(CustomXmlPartType.CustomXml);
using (StreamWriter ts = new StreamWriter(customXml.GetStream()))
{
ts.Write(newXml);
}
//closing WordprocessingDocument automatically saves the document
}
Console.WriteLine("Done");
Console.ReadLine();
}
Related
I am able to create a word doc using the code below.
Question: how do i create a pdf instead of word doc?
Code
using (StreamWriter outputFile = new StreamWriter(Path.Combine(docPath, tdindb.TDCode + "-test.doc")))
{
string html = string.Format("<html>{0}</html>", sbHtml);
outputFile.WriteLine(html);
}
string FileLocation = docPath + "\\" + tdindb.TDCode + "-test.doc";
byte[] fileBytes = System.IO.File.ReadAllBytes(FileLocation);
string fileName = Path.GetFileName(FileLocation);
return File(fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
Thank you
You need to use one of PDF creating libraries. I tried to use iText , IronPDF, and PDFFlow. All of them create PDF documents from scratch.
But PDFFlow was better for my case because i needed automatic page creation and multi-page spread table)
This is how to create a simple PDF file in C#:
{
var DocumentBuilder.New()
.AddSection()
.AddParagraphToSection("your text goes here!")
.ToSection()
.ToDocument()
.Build("Result.PDF");
}
feel free to ask me if you need more help.
Converting a Word document to HTML has been answered here before. The linked example is the first result of many on this site.
Once you have your HTML, to create a PDF you need to use a PDF creation library. For this example we will use IronPDF which requires just 3 lines of code:
string html = string.Format("<html>{0}</html>", sbHtml);
var renderer = new IronPdf.ChromePdfRenderer();
// Save PDF file to BinaryData
renderer.RenderHtmlAsPdf(html).BinaryData;
// Save file to location
renderer.RenderHtmlAsPdf(html).SaveAs("output.pdf");
I want to copy the content of a document file to another keeping it formatted. I found a way to copy the whole document to a new one using File.Copy(file, newFile, true); but I need to append the content to another existing one.
Here is a quick code sample that should get you on your way:
using Word = Microsoft.Office.Interop.Word;
var wdApp = new Word.Application();
var documents = wdApp.Documents;
var doc = documents.Open(newFile);
doc.Content.Collapse(Word.WdCollapseDirection.wdCollapseEnd);
doc.Content.InsertFile(file);
I'm looking to replace a bookmark in a word document with the entire contents of another word document. I was hoping to do something along the lines of the following, but appending the xml does not seem to be enough as it does not include pictures.
using Word = Microsoft.Office.Interop.Word;
...
Word.Application wordApp = new Word.Application();
Word.Document doc = wordApp.Documents.Add(filename);
var bookmark = doc.Bookmarks.OfType<Bookmark>().First();
var doc2 = wordApp.Documents.Add(filename2);
bookmark.Range.InsertXML(doc2.Contents.XML);
The second document contains a few images and a few tables of text.
Update: Progress made by using XML, but still doesn't satisfy adding pictures as well.
You've jumped in deep.
If you're using the object model (bookmark.Range) and trying to insert a picture you can use the clipboard or bookmark.Range.InlineShapes.AddPicture(...). If you're trying to insert a whole document you can copy/paste the second document:
Object objUnit = Word.WdUnits.wdStory;
wordApp.Selection.EndKey(ref objUnit, ref oMissing);
wordApp.ActiveWindow.Selection.PasteAndFormat(Word.WdRecoveryType.wdPasteDefault);
If you're using XML there may be other problems, such as formatting, images, headers/footers not coming in correctly.
Depending on the task it may be better to use DocumentBuilder and OpenXML SDK. If you're writing a Word addin you can use the object API, it will likely perform the same, if you're processing documents without Word go with OpenXML SDK and DocumentBuilder. The issue with DocumentBuilder is if it doesn't work there aren't many work-arounds to try. It's open source not the cleanest piece of code if you try troubleshooting it.
You can do this with openxml SDK and Document builder. To outline here is what you will need
1> Inject insert key in main doc
public WmlDocument GetProcessedTemplate(string templatePath, string insertKey)
{
WmlDocument templateDoc = new WmlDocument(templatePath);
using (MemoryStream mem = new MemoryStream())
{
mem.Write(templateDoc.DocumentByteArray, 0, templateDoc.DocumentByteArray.Length);
using (WordprocessingDocument doc = WordprocessingDocument.Open([source], true))
{
XDocument xDoc = doc.MainDocumentPart.GetXDocument();
XElement bookMarkPara = [get bookmarkPara to replace];
bookMarkPara.ReplaceWith(new XElement(PtOpenXml.Insert, new XAttribute("Id", insertKey)));
doc.MainDocumentPart.PutXDocument();
}
templateDoc.DocumentByteArray = mem.ToArray();
}
return templateDoc;
}
2> Use document builder to merge
List<Source> documentSources = new List<Source>();
var insertKey = "INSERT_HERE_1";
var processedTemplate = GetProcessedTemplate([docPath], insertKey);
documentSources.Add(new Source(processedTemplate, true));
documentSources.Add(new Source(new WmlDocument([docToInsertFilePath]), insertKey));
DocumentBuilder.BuildDocument(documentSources, [outputFilePath]);
Below is the code that creates a pdf to write a file..Every time i call the below code it creates a pdf file to write into..My question is,is there a same method for exporting to word or for simplicity just creates a blank doc file so that i can export data into it..
public void showPDf() {
iTextSharp.text.Document doc = new iTextSharp.text.Document(
iTextSharp.text.PageSize.A4);
string combined = Path.Combine(txtPath.Text,".pdf");
PdfWriter pw = PdfWriter.GetInstance(doc, new FileStream(combined, FileMode.Create));
doc.Open();
}
1. Interop API
It is available in Namespace Microsoft.Office.Interop.Word.
You can use Word Interop COM API to do that using following code,
// Open a doc file.
Application application = new Application();
Document document = application.Documents.Open("C:\\word.doc");
// Loop through all words in the document.
int count = document.Words.Count;
for (int i = 1; i <= count; i++)
{
// Write the word.
string text = document.Words[i].Text;
Console.WriteLine("Word {0} = {1}", i, text);
}
// Close word.
application.Quit();
Only Drawback is you must have office installed to use this feature.
2. OpenXML
you can use openxml to build word documents, try the following link,
http://msdn.microsoft.com/en-us/library/bb264572(v=office.12).aspx
Did you try searching the web for this ?
How to automate Microsoft Word to create a new document by using Visual C#
There is a free solution to export data to word,
http://www.codeproject.com/Articles/151789/Export-Data-to-Excel-Word-PDF-without-Automation-f
Using Word 2010 GUI, there is an option to "Insert text from file...", which does exactly that: It insert the text in the main part of a document to the current location in your document.
I would like to do the same using C# and the OpenXml SDK 2.0
using (var mainDocument = WordprocessingDocument.Open("MainFile.docx", true);
{
var mainPart = mainDocument.MainDocumentPart;
var bookmarkStart = mainPart
.Document
.Body
.Descendants<BookmarkStart>()
.SingleOrDefault(b => b.Name == "ExtraContentBookmark");
var extraContent = GetTextFromFile("ExtraFile.docx");
bookmarkStart.InsertAfterSelf(extraContent);
}
I have tried using plain Xml (XElement), using OpenXmlElement (MainDocumentPart.Document.Body.Descendants), and using AltChunk. Every alternative so far has yielded a non-conformant docx-file.
What should the method GetTextFromFile look like?
This is how I implemented it. The solution was to use AltChunk as described by Eric White. I had already tried it, but as Bradley said in his answer, a bookmark may be anywhere in a document, and mine was inside a paragraph. As soon as I inserted the text before the containing paragraph, everything worked fine.
Here is the (simplified) code:
using (var mainDocument = WordprocessingDocument.Open("MainFile.docx", true);
{
var mainPart = mainDocument.MainDocumentPart;
var bookmarkStart = mainPart
.Document
.Body
.Descendants<BookmarkStart>()
.SingleOrDefault(b => b.Name == "ExtraContentBookmark");
var altChunk = GetAltChunkFromFile("ExtraFile.docx", mainPart);
var containingParagraph = element.Ancestors<Paragraph>().FirstOrDefault();
containingParagraph.InsertBeforeSelf(altChunk);
}
...
private AltChunk GetAltChunk(string filename, MainDocumentPart mainDocumentPart)
{
var altChunkId = "AltChunkId1";
var chunk = mainDocumentPart.AddAlternativeFormatImportPart(
AlternativeFormatImportPartType.WordprocessingML, altChunkId);
chunk.FeedData(File.Open(filename, FileMode.Open));
var altChunk = new AltChunk { Id = altChunkId };
return altChunk;
}
It is not as simple as inserting the descendants of the document body tag at the bookmark location. Some reasons:
The two documents may be using different styles; you would have to copy across dependant styles, or update the references to use the styles in the destination document.
The <bookmarkStart> tag can appear almost anywhere in a document, including inside a paragraph, a run, a table cell, etc. Since you cannot nest paragraphs or runs, you will have to determine where the bookmark is situated, then ascend/descend the XML tree until you find an appropriate place to insert the content.
What you're trying to do becomes quite a complicated task when using the OpenXml SDK. It requires an in-depth understanding of the format and its schema.
I would almost advise using VSTO/OLE automation instead, as it enables you to use the functionality that is built into Word.