I want to convert XML to word template and when I used the code below when I open the word document it show all test like
(PK ! #qu é [Content_Types].xml ¢( Í•ËNÃ0E÷HüCämÕ¸ejÚ%T¢|€‰'©…c[÷‘¿gÒ´¡Ò ÚÒn"93÷Þck¤Œ–…ŽæàQY“°~Üc˜ÔJeò„½N»7, ŒÚHX ÈFÃË‹Á¤t€©
&l‚»åÓ)cëÀP%³¾Ž>çN¤ï" ~Õë]óÔš &tCåÁ†ƒ{ÈÄL‡èaI¿kYtW7VY Îi•Š#u>7ò[Jw“rÕƒSå°C)
my code like
string rootPath = #"xmlpath";
string templateDocument = #"mytemplateword documentpath";
string outputDocument = #"myoutputdocumentpath";
// word.Document wordDoc = wordApp.doc
// using (WordprocessingDocument doc =
// WordprocessingDocument.Create(xmlDataFile, WordprocessingDocumentType.Document,true))
//{
// MainDocumentPart mainPart = doc.AddMainDocumentPart();
// mainPart.Document = new Document();
// Body body = mainPart.Document.AppendChild(new Body());
// SectionProperties props = new SectionProperties();
// body.AppendChild(props);
//}
//Document doc = new Document();
string result = "";
MemoryStream mStream = new MemoryStream();
XmlTextWriter writer = new XmlTextWriter(mStream, System.Text.Encoding.Unicode);
XmlDocument document = new XmlDocument();
// XmlNodeList PatientFirst = xmlDoc.GetElementsByTagName("PatientFirst");
// XmlNodeList PatientSignatureImg = xmlDoc.GetElementsByTagName("PatientSignatureImg");
byte[] byteArray = System.IO.File.ReadAllBytes(templateDocument);
using (MemoryStream mem = new MemoryStream())
{
mem.Write(byteArray, 0, (int)byteArray.Length);
using (WordprocessingDocument Doc = WordprocessingDocument.Open(mem, true))
{
using (StreamReader reader = new StreamReader(Doc.MainDocumentPart.GetStream(FileMode.Create)))
{
documentText = reader.ReadToEnd();
}
using (StreamWriter docWriter = new StreamWriter(Doc.MainDocumentPart.GetStream(FileMode.Create)))
{
docWriter.Write(documentText);
}
}
System.IO.File.WriteAllBytes(outputDocument, mem.ToArray());
Related
I have two html strings, I'm trying to write both of them to 2 memoryStreams, then read one pdfDocument and CopyPagesTo to the other pdfDocument, then finally return the memoryStream with the combined documents.
{
string Document = "<p>Hello to All</p>";
string newPage = "<p>Additional Page</p>";
var mainStream = new MemoryStream();
using (PdfWriter pdfWriter = new PdfWriter(mainStream))
{
pdfWriter.SetCloseStream(false);
using (var document = HtmlConverter.ConvertToDocument(Document, pdfWriter)) { }
}
mainStream.Position = 0;
var newPageStream = new MemoryStream();
using (PdfWriter pdfWriter1 = new PdfWriter(newPageStream))
{
pdfWriter1.SetCloseStream(false);
using (var document = HtmlConverter.ConvertToDocument(newPage, pdfWriter1)) { }
};
mainStream = addNewPage(mainStream, newPageStream);
return mainStream;
}
Code to Add new page :
public static MemoryStream addNewPage(MemoryStream mainStream, MemoryStream newPageStream)
{
PdfWriter writer = new PdfWriter(mainStream);
PdfDocument pdfDoc = new PdfDocument(writer);
pdfDoc.InitializeOutlines();
PdfDocument addedDoc = new PdfDocument(new PdfReader(newPageStream));
addedDoc.CopyPagesTo(1, addedDoc.GetNumberOfPages(), pdfDoc);
mainStream.Position = 0;
using (PdfReader reader = new PdfReader(mainStream))
{
writer.SetCloseStream(false);
using (pdfDoc = new PdfDocument(reader, writer))
{
int z = pdfDoc.GetNumberOfPages();
}
}
addedDoc.Close();
return mainStream;
}
I have a rich text box which contains html formatted text as well as we can insert a copied images. I tried with AlternativeFormatImportPart and AltChunk method. It's generating the document but getting the below error. Please let me know what am I missing here.
MemoryStream ms;// = new MemoryStream(new UTF8Encoding(true).GetPreamble().Concat(Encoding.UTF8.GetBytes(h)).ToArray());
ms = new MemoryStream(HtmlToWord(fileContent));
//MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(h));
// Create alternative format import part.
AlternativeFormatImportPart chunk =
mainDocPart.AddAlternativeFormatImportPart(
"application/xhtml+xml", altChunkId);
chunk.FeedData(ms);
AltChunk altChunk = new AltChunk();
altChunk.Id = altChunkId;
public static byte[] HtmlToWord(String html)
{
const string filename = "test.docx";
if (File.Exists(filename)) File.Delete(filename);
var doc = new Document();
using (MemoryStream generatedDocument = new MemoryStream())
{
using (WordprocessingDocument package = WordprocessingDocument.Create(
generatedDocument, WordprocessingDocumentType.Document))
{
MainDocumentPart mainPart = package.MainDocumentPart;
if (mainPart == null)
{
mainPart = package.AddMainDocumentPart();
new Document(new Body()).Save(mainPart);
}
HtmlConverter converter = new HtmlConverter(mainPart);
converter.ExcludeLinkAnchor = true;
converter.RefreshStyles();
converter.ImageProcessing = ImageProcessing.AutomaticDownload;
//converter.BaseImageUrl = new Uri(domainNameURL + "Images/");
converter.ConsiderDivAsParagraph = false;
Body body = mainPart.Document.Body;
var paragraphs = converter.Parse(html);
for (int i = 0; i < paragraphs.Count; i++)
{
body.Append(paragraphs[i]);
}
mainPart.Document.Save();
}
return generatedDocument.ToArray();
}
}
There are some issues in AlternativeFormatImportPart with MemoryStream, document is not getting formatted well. So followed an alternate approach, using HtmlToWord method saved the html content into word and read the file content using FileStream and feed the AlternativeFormatImportPart.
string docFileName;
HtmlToWord(fileContent, out docFileName);
FileStream fileStream = File.Open(docFileName, FileMode.Open);
// Create alternative format import part.
AlternativeFormatImportPart chunk =mainDocPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML, altChunkId);
chunk.FeedData(fileStream);
AltChunk altChunk = new AltChunk();
altChunk.Id = altChunkId;
I open document and copy to the stream.
How I can replace some text in document before stream?
//wordTemplate - var with path to my word template
byte[] result = null;
byte[] templateBytes = System.IO.File.ReadAllBytes(wordTemplate);
using (MemoryStream templateStream = new MemoryStream())
{
templateStream.Write(templateBytes, 0, (int)templateBytes.Length);
using (WordprocessingDocument doc = WordprocessingDocument.Open(templateStream, true))
{
MainDocumentPart mainPart = doc.MainDocumentPart;
mainPart.Document.Save();
templateStream.Position = 0;
using (MemoryStream memoryStream = new MemoryStream())
{
templateStream.CopyTo(memoryStream);
result = memoryStream.ToArray();
}
}
}
Instead of calling File.ReadAllBytes(), why not call File.ReadAllLines(string) instead? It gives you an array of strings, which you can then can search and replace to your hearts delight.
I'm using the following code to generate an openxml document and save it on the server and that works fine, however now i'm trying to generate it to a byte stream to serve out straight away without saving to the server but the document gets corrupted in the process.
Working Code
public static void CreateWordDoc(List<objReplace> lstReplace, String TemplateFile, String OutputPath)
{
File.Delete(OutputPath);
File.Copy(TemplateFile, OutputPath);
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(OutputPath, true))
{
string docText = null;
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
docText = sr.ReadToEnd();
foreach (var ro in lstReplace)
{
Regex regexText = new Regex(ro.Find);
docText = regexText.Replace(docText, ro.Replace);
}
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
}
}
}
Code that produces currupted XML - that I want to get working
public static byte[] CreateWordDocToStream(List<objReplace> lstReplace, String TemplateFile)
{
string docText = null;
byte[] filebytes = File.ReadAllBytes(TemplateFile);
using (MemoryStream stream = new MemoryStream(filebytes))
{
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(stream, true))
{
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
docText = sr.ReadToEnd();
foreach (var ro in lstReplace)
{
Regex regexText = new Regex(ro.Find);
docText = regexText.Replace(docText, ro.Replace);
}
}
}
return Encoding.ASCII.GetBytes(docText);
}
I am creating a sample handler to generate simple Word document.
This document will contains the text Hello world
This is the code I use (C# .NET 3.5),
I got the Word document created but there is no text in it, the size is 0.
How can I fix it?
(I use CopyStream method because CopyTo is available in .NET 4.0 and above only.)
public class HandlerCreateDocx : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
using (MemoryStream mem = new MemoryStream())
{
// Create Document
using (WordprocessingDocument wordDocument =
WordprocessingDocument.Create(mem, WordprocessingDocumentType.Document, true))
{
// Add a main document part.
MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();
// Create the document structure and add some text.
mainPart.Document = new Document();
Body body = mainPart.Document.AppendChild(new Body());
Paragraph para = body.AppendChild(new Paragraph());
Run run = para.AppendChild(new Run());
run.AppendChild(new Text("Hello world!"));
mainPart.Document.Save();
// Stream it down to the browser
context.Response.AppendHeader("Content-Disposition", "attachment;filename=HelloWorld.docx");
context.Response.ContentType = "application/vnd.ms-word.document";
CopyStream(mem, context.Response.OutputStream);
context.Response.End();
}
}
}
// Only useful before .NET 4
public void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[16 * 1024]; // Fairly arbitrary size
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
}
}
This works for me, by putting the streaming code in the outer USING block.
This causes a call to WordprocessingDocument.Close (via the Dispose method).
public void ProcessRequest(HttpContext context)
{
using (MemoryStream mem = new MemoryStream())
{
// Create Document
using (WordprocessingDocument wordDocument =
WordprocessingDocument.Create(mem, WordprocessingDocumentType.Document, true))
{
// Add a main document part.
MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();
// Create the document structure and add some text.
mainPart.Document = new Document();
Body body = mainPart.Document.AppendChild(new Body());
Paragraph para = body.AppendChild(new Paragraph());
Run run = para.AppendChild(new Run());
run.AppendChild(new Text("Hello world!"));
mainPart.Document.Save();
}
context.Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
context.Response.AppendHeader("Content-Disposition", "attachment;filename=HelloWorld.docx");
mem.Seek(0, SeekOrigin.Begin);
mem.CopyTo(context.Response.OutputStream);
context.Response.Flush();
context.Response.End();
}
}
I have modifed your code to make it work. I can open it correctly after save download it.
Please see my modified below. Hope this help.
using (MemoryStream documentStream = new MemoryStream())
{
using (WordprocessingDocument myDoc = WordprocessingDocument.Create(documentStream, WordprocessingDocumentType.Document, true))
{
// Add a new main document part.
MainDocumentPart mainPart = myDoc.AddMainDocumentPart();
//Create Document tree for simple document.
mainPart.Document = new Document();
//Create Body (this element contains
//other elements that we want to include
Body body = new Body();
//Create paragraph
Paragraph paragraph = new Paragraph();
Run run_paragraph = new Run();
// we want to put that text into the output document
Text text_paragraph = new Text("Hello World!");
//Append elements appropriately.
run_paragraph.Append(text_paragraph);
paragraph.Append(run_paragraph);
body.Append(paragraph);
mainPart.Document.Append(body);
// Save changes to the main document part.
mainPart.Document.Save();
myDoc.Close();
context.Response.ClearContent();
context.Response.ClearHeaders();
context.Response.ContentEncoding = System.Text.Encoding.UTF8;
SetContentType(context.Request, context.Response, "Simple.docx");
documentStream.Seek(0, SeekOrigin.Begin);
documentStream.CopyTo(context.Response.OutputStream);
context.Response.Flush();
context.Response.End();
}
}
string Filepath = #"C:\Users\infinity\Desktop\zoyeb.docx";
using (var wordprocessingDocument = WordprocessingDocument.Create(Filepath, DocumentFormat.OpenXml.WordprocessingDocumentType.Document))
{
MainDocumentPart mainPart = wordprocessingDocument.AddMainDocumentPart();
mainPart.Document = new DocumentFormat.OpenXml.Wordprocessing.Document();
Body body = mainPart.Document.AppendChild(new Body());
DocumentFormat.OpenXml.Wordprocessing.Paragraph para = body.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Paragraph());
DocumentFormat.OpenXml.Wordprocessing.Run run = para.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Run());
run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text("siddiq"));
wordprocessingDocument.MainDocumentPart.Document.Save();
}
go to nuget package manager and install this first into your project
Install-Package DocumentFormat.OpenXml -Version 2.8.1