ASP.NET + C#. Creating word document from template - c#

I have a word document which contains only one page filled with text and graphic. The page also contains some placeholders like [Field1],[Field2],..., etc.
I get data from database and I want to open this document and fill placeholders with some data. For each data row I want to open this document, fill placeholders with row's data and then concatenate all created documents into one document.
What is the best and simpliest way to do this?

Instead of some third party i will suggest you openXML
add following namespaces System.Text.RegularExpressions;
DocumentFormat.OpenXml.Packaging; and DocumentFormat.OpenXml.Wordprocessing;
public static void SearchAndReplace(string document)
{
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, true))
{
string docText = null;
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
}
Regex regexText = new Regex("Hello world!");
docText = regexText.Replace(docText, "Hi Everyone!");
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
}
}
}

You'll probably need to use a third party library.
You might want to check out http://www.codeproject.com/Articles/660478/Csharp-Create-and-Manipulate-Word-Documents-Progra
The below section specifically discusses replacing values in a Word document.
http://www.typecastexception.com/post/2013/09/28/C-Create-and-Manipulate-Word-Documents-Programmatically-Using-DocX.aspx#Find-and-Replace-Text-Using-DocX---Merge-Templating--Anyone-

Related

C# creating Word file - Error opening file

I am creating some word files (and replacing some words) from word template using this code snippet:
File.Copy(sourceFile, destinationFile, true);
try
{
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(destinationFile, true))
{
string docText = null;
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
}
foreach (KeyValuePair<string, string> item in keyValues)
{
Regex regexText = new Regex(item.Key);
docText = regexText.Replace(docText, item.Value);
}
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
}
}
}
But when I am trying to open the produced file I get this error:
We're sorry. We can't open XXX.docx because we found a problem with its contents
XML parsing error Location:Part:/word/document.xml, Line:2, Column:33686
Here are the contents of document.xml in the specific place:
.....<w:szCs w:val="20"/><w:lang w:val="en-US"/></w:rPr><w:t> </w:t></w:r><w:proofErr w:type="spellEnd"/>....
Where 33686 is the position of the &nbsp. How I can fix that problem?
EDIT In another file that produced correctly in the same position there are some random characters I used for testing which are used also in the title of the document
It looks like you're using regular expressions to directly modify XML, which is typically going to lead to difficult-to-troubleshoot issues like this, especially if any of your regexes match anything that could be interpreted as XML.
As an alternative, you may want to investigate that WordProcessDocument class more deeply. It looks like it has strongly-typed objects like Paragraph that you can modify more safely.

Replacing Template Fields in Word Documents with OpenXML

I am trying to create a templating system with OpenXML in our Azure app service-based application (so no Interop) and am running into issues with getting it to work. Here is the code I am currently working with (contents is a byte array):
using(MemoryStream stream = new MemoryStream(contents))
{
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(stream, true))
{
string docText = null;
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
}
Regex regexText = new Regex("<< Company.Name >>");
docText = regexText.Replace(docText, "Company 123");
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
}
wordDoc.Save();
}
updated = stream.ToArray();
}
The search text is not being found/replaced, which I am assuming is because of the way everything is stored separately in the XML, but how would I go about replacing a field like this?
Thanks
Ryan
With OpenXML SDK you can use this SearchAndReplace - Youtube, note that it's a screen cast that shows the algorithm that can be used to accomplish the replacement over multiple <w:run> elements.
An alternative approach would be to use pure .NET solution, like this Find and Replace text in a Word document.
Last, the easiest and straightforward approach would be to use some other library, for instance check this example of Find and Replace with GemBox.Document.

Inserting a doc file inplace of place holder

I have a word document which contain many pages. One of those pages contain a placeholder instead of other content. so I want to replace that placeholder with another doc file without losing formatting. This doc file which is to be replaced may have many pages. How can I replace that placeholder with this doc file programmatically.. I searched many but could not find any option to insert a doc file replacing a placeholder.. Thank You In Advance.
Or how can we copy the contents of doc to be inserted and then replace the placeholder with copied content
I found a post here.The below code is from that post.
With the library, you can do the following to replace text from a Word document, considering that documentByteArray is your document byte content taken from database:
using (MemoryStream mem = new MemoryStream())
{
mem.Write(documentByteArray, 0, (int)documentByteArray.Length);
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, true))
{
string docText = null;
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
}
Regex regexText = new Regex("Hello world!");
docText = regexText.Replace(docText, "Hi Everyone!");
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
}
}
}
if instead of "Hi Everyone" if we replace it with a binarydata,which is an array of bytes
byte[] binarydata = File.ReadAllBytes(filepaths);
how can we modify the program?
First of all you should get a Nuget package called Novacode.Docx, this is what I have found to be the best Document creator and editor in the last few years.
using Novacode.Docx;
void Main()
{
var doc = DocX.Load(#"c:\temp\existingDoc.docx");
var docToAdd = DocX.Load(#"c:\temp\docToAdd.docx");
doc.InsertDocument(docToAdd, true); //version 1.0.0.22
doc.InsertDocument(docToAdd); //version 1.0.0.19
}
this is the most simple and basic implementation of what it is that youre after but this works.
for anything else take a look at the documentation at
https://docx.codeplex.com/
or
http://cathalscorner.blogspot.co.uk/
this will be the best place to start. I would also recommend that if you do use this one that you use the version 1.0.0.19 as there are some formatting issues in 1.0.0.22

streamReader.ReadToEnd() return just header OpenXML

Please, I want to find a word and replace it with another word in word doccument using openXML
  I use this method
public static void AddTextToWord(string filepath, string txtToFind,string ReplaceTxt)
{
WordprocessingDocument wordDoc = WordprocessingDocument.Open(filepath, true);
string docText = null;
StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream());
docText = sr.ReadToEnd();
System.Diagnostics.Debug.WriteLine(docText);
Regex regexText = new Regex(txt);
docText = regexText.Replace(docText,txt2);
StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create));
System.Diagnostics.Debug.WriteLine(docText);
wordDoc.Close();
}
but
docText
return just the head of the page that the xml shema of the document.
<?xml version="1.0" encoding=.......
Check Your Strings
If you want to replace a specific word or phrase within your existing content, you may just want to use the String.Replace() method as opposed to performing a Regex.Replace() which may not work as expected (as it expects a regular expression as opposed to a traditional string). This may not matter if you expect to use regular expressions, but it's worth noting.
Ensure You Are Pulling The Content
Word Documents are obviously not as easy to parse as plain text, so in order to get the actual "content", you may have to use an approach similar to the one mentioned here that targets the Document.Body properties instead of reading using a StreamReader object :
docText = wordDoc.MainDocumentPart.Document.Body.InnerText;
Performing Your Replacement
With that said, you currently appear to be reading the contents of your file and storing it in a string called docText. Since you have that string and know your values to find and replace, just call the Replace() method as seen below :
docText = docText.Replace(txtToFind,ReplaceTxt);
Writing Out Your Content
After performing the replacement, you'll just need to write your updated text out to a stream :
using (var sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
}

Convert HTML or PDF to RTF/DOC or HTML/PDF to image using DevExpress or Infragistics

There is a way do convert HTML or PDF to RTF/DOC or HTML/PDF to image using DevExpress or Infragistics?
I tried this using DevExpress:
string html = new StreamReader(Server.MapPath(#".\teste.htm")).ReadToEnd();
RichEditControl richEditControl = new RichEditControl();
string rtf;
try
{
richEditControl.HtmlText = html;
rtf = richEditControl.RtfText;
}
finally
{
richEditControl.Dispose();
}
StreamWriter sw = new StreamWriter(#"D:\teste.rtf");
sw.Write(rtf);
sw.Close();
But I have a complex html content (tables, backgrounds, css etc) and the final result is not good...
To convert Html content into image or Pdf you may use the following code:
using (RichEditControl richEditControl = new RichEditControl()) {
richEditControl.LoadDocument(Server.MapPath(#".\teste.htm"), DocumentFormat.Html);
using (PrintingSystem ps = new PrintingSystem()) {
PrintableComponentLink pcl = new PrintableComponentLink(ps);
pcl.Component = richEditControl;
pcl.CreateDocument();
//pcl.PrintingSystem.ExportToPdf("teste.pdf");
pcl.PrintingSystem.ExportToImage("teste.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
I suggest you to use latest DevExpress version (version 10.1.5 this time). It handles tables much better than previous ones.
Please use the following code to avoid encoding issues (StreamReader and StreamWriter in your sample always use Encoding.UTF8 encoding, this will corrupt any content stored with another encoding):
using (RichEditControl richEditControl = new RichEditControl()) {
richEditControl.LoadDocument(Server.MapPath(#".\teste.htm"), DocumentFormat.Html);
richEditControl.SaveDocument(#"D:\teste.rtf", DocumentFormat.Rtf);
}
Also take a look at the richEditControl.Options.Import.Html and richEditControl.Options.Export.Rtf properties, you may find them useful for some cases.

Categories