I am creating a simple word doc, using the openXml SDK.
It is working so far.
Now how can I add an image from my file system to this doc? I don't care where it is in the doc just so it is there.
Thanks!
Here is what I have so far.
string fileName = "proposal"+dealerId +Guid.NewGuid().ToString()+".doc";
string filePath = #"C:\DWSApplicationFiles\Word\" + fileName;
using (WordprocessingDocument wordDoc = WordprocessingDocument.Create(filePath, WordprocessingDocumentType.Document, true))
{
MainDocumentPart mainPart = wordDoc.AddMainDocumentPart();
mainPart.Document = new Document();
//create the body
Body body = new Body();
DocumentFormat.OpenXml.Wordprocessing.Paragraph p = new DocumentFormat.OpenXml.Wordprocessing.Paragraph();
DocumentFormat.OpenXml.Wordprocessing.Run runParagraph = new DocumentFormat.OpenXml.Wordprocessing.Run();
DocumentFormat.OpenXml.Wordprocessing.Text text_paragraph = new DocumentFormat.OpenXml.Wordprocessing.Text("This is a test");
runParagraph.Append(text_paragraph);
p.Append(runParagraph);
body.Append(p);
mainPart.Document.Append(body);
mainPart.Document.Save();
}
Here is a method that can be simpler than the one described in the msdn page posted above, this code is in C++/CLI but of course you can write the equivalent in C#
WordprocessingDocument^ doc = WordprocessingDocument::Open(doc_name, true);
FileStream^ img_fs = gcnew FileStream(image_path, FileMode::Open);
ImagePart^ image_part = doc->MainDocumentPart->AddImagePart(ImagePartType::Jpeg);
image_part->FeedData(img_fs);
Run^ img_run = doc->MainDocumentPart->Document->Body->AppendChild(gcnew Paragraph())->AppendChild(gcnew Run());
Vml::ImageData^ img_data = img_run->AppendChild(gcnew Picture())->AppendChild(gcnew Vml::Shape())->AppendChild(gcnew Vml::ImageData());
img_data->RelationshipId = doc->MainDocumentPart->GetIdOfPart(image_part);
doc->Close();
This code worked for me: http://msdn.microsoft.com/en-us/library/bb497430.aspx
Your code adds image to your docx package, but in order to see it in the document you have to declare it in your document.xml i.e. link it to your physical image. That's why you have to write that long function listed in the msdn link.
My problem is how to add effects to pictures (editing, croping, background removal).
If you know how to do this I'd appreciate your help :)
How to: Add an Image Part to an Office Open XML Package by Using the Open XML API
http://msdn.microsoft.com/en-us/library/bb497430(v=office.12).aspx
public static void AddImagePart(string document, string fileName)
{
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, true))
{
MainDocumentPart mainPart = wordDoc.MainDocumentPart;
ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Jpeg);
using (FileStream stream = new FileStream(fileName, FileMode.Open))
{
imagePart.FeedData(stream);
}
}
}
Related
I am creating a PDF Document consisting 6 images (1 Image on 1 Page) using iTextSharp.
I need to add a HTML Page as a last page after the 6th Image.
I have tried the below, but the HTML does not get added on a new page, instead gets attached immediately below the 5th Image.
Please advice how to make the html add to the last page.
Code for reference:
string ImagePath = HttpContext.Current.Server.MapPath("~/Images/");
string[] fileNames = System.IO.Directory.GetFiles(ImagePath);
string outputFileNames = "Test.pdf";
string outputFilePath = System.Web.Hosting.HostingEnvironment.MapPath("~/Pdf/" + outputFileNames);
Document doc = new Document(PageSize.A4, 20, 20, 20, 20);
System.IO.Stream st = new FileStream(outputFilePath, FileMode.Create, FileAccess.Write);
PdfWriter writer = PdfWriter.GetInstance(doc, st);
doc.Open();
writer.PageEvent = new Footer();
for (int i = 0; i < fileNames.Length; i++)
{
string fname = fileNames[i];
if (System.IO.File.Exists(fname) && Path.GetExtension(fname) == ".png")
{
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(fname);
img.Border = iTextSharp.text.Rectangle.BOX;
img.BorderColor = iTextSharp.text.BaseColor.BLACK;
doc.Add(img);
}
}
byte[] pdf; // result will be here
var cssText = File.ReadAllText(MapPath("~/Style1.css"));
var html = File.ReadAllText(MapPath("~/HtmlPage1.html"));
using ( var memoryStream = new MemoryStream())
{
using (var cssMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(cssText)))
{
using (var htmlMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(html)))
{
XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, htmlMemoryStream, cssMemoryStream);
}
}
pdf = memoryStream.ToArray();
//document.Add(new Paragraph(Encoding.UTF8.GetString(pdf)));
}
doc.NewPage();
doc.Add(new Paragraph(Encoding.UTF8.GetString(pdf)));
doc.Close();
writer.Close();
I need to add a HTML Page as a last page after the 6th Image.
Any help is appreciated
In contrast to what you assume according to your code comments, pdf is not where the result will be. It remains empty:
byte[] pdf; // result will be here
...
using ( var memoryStream = new MemoryStream())
{
... code not accessing memoryStream ...
pdf = memoryStream.ToArray();
//document.Add(new Paragraph(Encoding.UTF8.GetString(pdf)));
}
doc.NewPage();
doc.Add(new Paragraph(Encoding.UTF8.GetString(pdf)));
Thus, you add the new page before adding an empty paragraph, after the converted html already has been added to the document.
Actually it is added during
XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, htmlMemoryStream, cssMemoryStream);
So you have to add the new page before that. Thus, the following replacing everything from your byte[] pdf; on should do the job:
var cssText = File.ReadAllText(MapPath("~/Style1.css"));
var html = File.ReadAllText(MapPath("~/HtmlPage1.html"));
using (var cssMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(cssText)))
{
using (var htmlMemoryStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(html)))
{
doc.NewPage();
XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, htmlMemoryStream, cssMemoryStream);
}
}
doc.Close();
As an aside, don't close the writer! It implicitly is closed when the doc is closed. Closing it again does nothing at best or damage otherwise.
In a comment you claimed
but this also does not resolve the issue... the pdf content still get added after the image and then continued on new page.
So I tested the proposed change. Obviously I don't have your environment and also not your image, html, and css files. Thus, I used own ones, a small screen shot and "<html><body><h1>Test</h1><p>This is a test piece of html</p></body></html>".
With your code I get:
With the code changed as described above I get
My impression here is that the proposed code change does resolve the issue. The html content is added on a new page.
Thus apparently your either incorrectly applied the proposed change, or you executed old code, or you inspected some old result.
As the title states I am trying to merge multiple word(.docx) files into one word doc. Each of these documents is one page long. I am using some of the code from this post in this implementation. The issue I am running into is that only the first document gets written properly, every other iteration appends a new document but the document contents is the same as the first.
Here is the code I am using:
//list that holds the file paths
List<String> fileNames = new List<string>();
fileNames.Add("filePath");
fileNames.Add("filePath");
fileNames.Add("filePath");
fileNames.Add("filePath");
fileNames.Add("filePath");
//get the first document
MemoryStream mainStream = new MemoryStream();
byte[] buffer = File.ReadAllBytes(fileNames[0]);
mainStream.Write(buffer, 0, buffer.Length);
using (WordprocessingDocument mainDocument = WordprocessingDocument.Open(mainStream, true))
{
//xml for the new document
XElement newBody = XElement.Parse(mainDocument.MainDocumentPart.Document.Body.OuterXml);
//iterate through eacah file
for (int i = 1; i < fileNames.Count; i++)
{
//read in the document
byte[] tempBuffer = File.ReadAllBytes(fileNames[i]);
WordprocessingDocument tempDocument = WordprocessingDocument.Open(new MemoryStream(tempBuffer), true);
//new documents XML
XElement tempBody = XElement.Parse(tempDocument.MainDocumentPart.Document.Body.OuterXml);
//add the new xml
newBody.Add(tempBody);
string str = newBody.ToString();
//write to the main document and save
mainDocument.MainDocumentPart.Document.Body = new Body(newBody.ToString());
mainDocument.MainDocumentPart.Document.Save();
mainDocument.Package.Flush();
tempBuffer = null;
}
//write entire stream to new file
FileStream fileStream = new FileStream("xmltest.docx", FileMode.Create);
mainStream.WriteTo(fileStream);
//ret = mainStream.ToArray();
mainStream.Close();
mainStream.Dispose();
}
Again the problem is that each new document being created has the same content as the first document. So when I run this the output will be a document with five identical pages. I've tried switching the documents order around in the list and get the same result so it is nothing specific to one document.
Could anyone suggest what I am doing wrong here? I'm looking through it and I can't explain the behavior I am seeing. Any suggestions would be appreciated. Thanks much!
Edit: I'm thinking this may have something to do with that fact that the documents I am trying to merge have been generated with custom XML parts. I'm thinking that the Xpath in the documents are somehow pointing to the same content. The thing is I can open each of these documents and see the proper content, it's just when I merge them that I see the issue.
This solution uses DocumentFormat.OpenXml
public static void Join(params string[] filepaths)
{
//filepaths = new[] { "D:\\one.docx", "D:\\two.docx", "D:\\three.docx", "D:\\four.docx", "D:\\five.docx" };
if (filepaths != null && filepaths.Length > 1)
using (WordprocessingDocument myDoc = WordprocessingDocument.Open(#filepaths[0], true))
{
MainDocumentPart mainPart = myDoc.MainDocumentPart;
for (int i = 1; i < filepaths.Length; i++)
{
string altChunkId = "AltChunkId" + i;
AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(
AlternativeFormatImportPartType.WordprocessingML, altChunkId);
using (FileStream fileStream = File.Open(#filepaths[i], FileMode.Open))
{
chunk.FeedData(fileStream);
}
DocumentFormat.OpenXml.Wordprocessing.AltChunk altChunk = new DocumentFormat.OpenXml.Wordprocessing.AltChunk();
altChunk.Id = altChunkId;
//new page, if you like it...
mainPart.Document.Body.AppendChild(new Paragraph(new Run(new Break() { Type = BreakValues.Page })));
//next document
mainPart.Document.Body.InsertAfter(altChunk, mainPart.Document.Body.Elements<Paragraph>().Last());
}
mainPart.Document.Save();
myDoc.Close();
}
}
The way you seem to merge may not work properly at times. You can try one of the approaches
Using AltChunk as in http://blogs.msdn.com/b/ericwhite/archive/2008/10/27/how-to-use-altchunk-for-document-assembly.aspx
Using http://powertools.codeplex.com/ DocumentBuilder.BuildDocument method
If still you face the similar issue you can find the databound controls prior to Merge and
assign data to these controls from the CustomXml part. You can find this approach in method AssignContentFromCustomXmlPartForDataboundControl of OpenXmlHelper class. The code can be downloaded from http://worddocgenerator.codeplex.com/
I am trying to generate a .pdf from html using the library ITextSharp. I am able to create the pdf with the html text converted to pdf text/paragraphs
My Problem: The pdf does not show my images(my img elements from the html). All my img html elements in my html dont get displayed in the pdf? Is it possible for ITextSharp to parse HTML & display images. I really hope so otherwise I am stuffed :(
I am linking to the correct directory where the images are(using IMG_BASURL) but they are just not showing
My code:
// mainContents variable is a string containing my HTML
var document = new Document(PageSize.A4, 50, 50, 80, 100);
var output = new MemoryStream();
var writer = PdfWriter.GetInstance(document, output);
document.open();
Hashtable providers = new Hashtable();
providers.Add("img_baseurl","C:/users/xx/VisualStudio/Projects/myproject/");
var parsedHtmlElements = HTMLWorker.ParseToList(new StringReader(mainContents), null, providers);
foreach (var htmlElement in parsedHtmlElements)
document.Add(htmlElement as IElement);
document.Close();
Every time that I've encountered this the problem was that the image was too large for the canvas. More specifically, even a naked IMG tag internally will get wrapped in a Chunk that will get wrapped in a Paragraph, and I think that the image is overflowing the Paragraph but I'm not 100% sure.
The two easy fixes are to either enlarge the canvas or to specify image dimensions on the HTML IMG tag. The third more complex route would be to use an additional provider IMG_PROVIDER. To do this you need to implement the IImageProvider interface. Below is a very simple version of one
public class ImageThing : IImageProvider {
//Store a reference to the main document so that we can access the page size and margins
private Document MainDoc;
//Constructor
public ImageThing(Document doc) {
this.MainDoc = doc;
}
Image IImageProvider.GetImage(string src, IDictionary<string, string> attrs, ChainedProperties chain, IDocListener doc) {
//Prepend the src tag with our path. NOTE, when using HTMLWorker.IMG_PROVIDER, HTMLWorker.IMG_BASEURL gets ignored unless you choose to implement it on your own
src = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + #"\" + src;
//Get the image. NOTE, this will attempt to download/copy the image, you'd really want to sanity check here
Image img = Image.GetInstance(src);
//Make sure we got something
if (img == null) return null;
//Determine the usable area of the canvas. NOTE, this doesn't take into account the current "cursor" position so this might create a new blank page just for the image
float usableW = this.MainDoc.PageSize.Width - (this.MainDoc.LeftMargin + this.MainDoc.RightMargin);
float usableH = this.MainDoc.PageSize.Height - (this.MainDoc.TopMargin + this.MainDoc.BottomMargin);
//If the downloaded image is bigger than either width and/or height then shrink it
if (img.Width > usableW || img.Height > usableH) {
img.ScaleToFit(usableW, usableH);
}
//return our image
return img;
}
}
To use this provider just add it to the provider collection like you did with HTMLWorker.IMG_BASEURL:
providers.Add(HTMLWorker.IMG_PROVIDER, new ImageThing(doc));
It should be noted that if you use HTMLWorker.IMG_PROVIDER that you are responsible for figuring out everything about the image. The code above assumes that all image paths need to be prepended with a constant string, you'll probably want to update this and check for HTTP at the start. Also, because we're saying that we want to completely handle the image processing pipeline the provider HTMLWorker.IMG_BASEURL is no longer needed.
The main code loop would now look something like this:
string html = #"<img src=""Untitled-1.png"" />";
string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "HtmlTest.pdf");
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
using (Document doc = new Document(PageSize.A4, 50, 50, 80, 100)) {
using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) {
doc.Open();
using (StringReader sr = new StringReader(html)) {
System.Collections.Generic.Dictionary<string, object> providers = new System.Collections.Generic.Dictionary<string, object>();
providers.Add(HTMLWorker.IMG_PROVIDER, new ImageThing(doc));
var parsedHtmlElements = HTMLWorker.ParseToList(sr, null, providers);
foreach (var htmlElement in parsedHtmlElements) {
doc.Add(htmlElement as IElement);
}
}
doc.Close();
}
}
}
One last thing, make sure to specify which version of iTextSharp you are targetting when posting here. The code above targets iTextSharp 5.1.2.0 but I think you might be using the 4.X series.
I faced the same problem and tried the following proposed solutions:
string replaced a tag, encode in base64 and embed the image to a .NET class library but none worked !
So I've come to the old fashioned solution: adding the logo manually with doc.Add()
Here's your code updated:
string html = #"<img src=""Untitled-1.png"" />";
string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "HtmlTest.pdf");
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
using (Document doc = new Document(PageSize.A4, 50, 50, 80, 100)) {
using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) {
doc.Open();
using (StringReader sr = new StringReader(html)) {
System.Collections.Generic.Dictionary<string, object> providers = new System.Collections.Generic.Dictionary<string, object>();
providers.Add(HTMLWorker.IMG_PROVIDER, new ImageThing(doc));
var parsedHtmlElements = HTMLWorker.ParseToList(sr, null, providers);
foreach (var htmlElement in parsedHtmlElements) {
doc.Add(htmlElement as IElement);
}
// here's the magic
var logo = iTextSharp.text.Image.GetInstance(Server.MapPath("~/HTMLTemplate/logo.png"));
logo.SetAbsolutePosition(440, 800);
document.Add(logo);
// end
}
doc.Close();
}
}
}
string siteUrl = HttpContext.Current.Server.MapPath("/images/image/ticket/Ticket.jpg");
string HTML = "<table><tr><td><u>asdasdsadasdsa <img src='" + siteUrl + "' al='tt' /> </u></td></tr></table>";
I'm attempting to open a Word document, change some text and then save the changes to a new document. I can get the first bit done using the code below but I can't figure out how to save the changes to a NEW document (specifying the path and file name).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using DocumentFormat.OpenXml.Packaging;
using System.IO;
namespace WordTest
{
class Program
{
static void Main(string[] args)
{
string template = #"c:\data\hello.docx";
string documentText;
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(template, true))
{
using (StreamReader reader = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
documentText = reader.ReadToEnd();
}
documentText = documentText.Replace("##Name##", "Paul");
documentText = documentText.Replace("##Make##", "Samsung");
using (StreamWriter writer = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
writer.Write(documentText);
}
}
}
}
}
I'm a complete beginner at this, so forgive the basic question!
If you use a MemoryStream you can save the changes to a new file like this:
byte[] byteArray = File.ReadAllBytes("c:\\data\\hello.docx");
using (MemoryStream stream = new MemoryStream())
{
stream.Write(byteArray, 0, (int)byteArray.Length);
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(stream, true))
{
// Do work here
}
// Save the file with the new name
File.WriteAllBytes("C:\\data\\newFileName.docx", stream.ToArray());
}
In Open XML SDK 2.5:
File.Copy(originalFilePath, modifiedFilePath);
using (var wordprocessingDocument = WordprocessingDocument.Open(modifiedFilePath, isEditable: true))
{
// Do changes here...
}
wordprocessingDocument.AutoSave is true by default so Close and Dispose will save changes.
wordprocessingDocument.Close is not needed explicitly because the using block will call it.
This approach doesn't require entire file content to be loaded into memory like in accepted answer. It isn't a problem for small files, but in my case I have to process more docx files with embedded xlsx and pdf content at the same time so the memory usage would be quite high.
Simply copy the source file to the destination and make changes from there.
File.copy(source,destination);
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(destination, true))
{
\\Make changes to the document and save it.
wordDoc.MainDocumentPart.Document.Save();
wordDoc.Close();
}
Hope this works.
This approach allows you to buffer the "template" file without batching the whole thing into a byte[], perhaps allowing it to be less resource intensive.
var templatePath = #"c:\data\hello.docx";
var documentPath = #"c:\data\newFilename.docx";
using (var template = File.OpenRead(templatePath))
using (var documentStream = File.Open(documentPath, FileMode.OpenOrCreate))
{
template.CopyTo(documentStream);
using (var document = WordprocessingDocument.Open(documentStream, true))
{
//do your work here
document.MainDocumentPart.Document.Save();
}
}
For me this worked fine:
// To search and replace content in a document part.
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);
}
}
}
I am trying to create an AddAlternativeFormatImportPart in a .docx file in order to reference it in the document via an AltChunk. the problem is that the code below causes the docx file to read as corrupted by Word and cannot be opened.
string html = "some html code."
string altChunkId = "html234";
var document = WordprocessingDocument.Open(inMemoryPackage, true);
var mainPart = document.MainDocumentPart.Document;
var mainDocumentPart = document.MainDocumentPart;
AlternativeFormatImportPart chunk = mainDocumentPart.AddAlternativeFormatImportPart
(AlternativeFormatImportPartType.Xhtml, altChunkId);
Stream contentStream = chunk.GetStream(FileMode.Open,FileAccess.ReadWrite);
StreamWriter contentWriter = new StreamWriter(contentStream);
contentWriter.Write(html);
contentWriter.Flush();
{
...
}
mainPart.Save();
I think it might be how you are handeling the stream from the AlternativeFormatImportPart. Try using FeedData instead, like in my example below.
StringBuilder xhtmlBuilder = new StringBuilder();
xhtmlBuilder.Append("<html>");
xhtmlBuilder.Append("<body>");
xhtmlBuilder.Append("<b>Hello world!</b>");
xhtmlBuilder.Append("</body>");
xhtmlBuilder.Append("</html>");
using (WordprocessingDocument doc = WordprocessingDocument.Open(inputFilePath, true))
{
string altChunkId = "chunk1";
AlternativeFormatImportPart chunk = doc.MainDocumentPart.AddAlternativeFormatImportPart
(AlternativeFormatImportPartType.Xhtml, altChunkId);
using (MemoryStream xhtmlStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(xhtmlBuilder.ToString())))
{
chunk.FeedData(xhtmlStream);
AltChunk altChunk = new AltChunk();
altChunk.Id = altChunkId;
doc.MainDocumentPart.Document.Body.Append(altChunk);
}
doc.MainDocumentPart.Document.Save();
}
I think it is because you cannot import an AltChunk into a document that is opened from a memory stream. I had the same issue. I was opening the template from a memory stream like so:
Private Sub UpdateDoc(templatePath As String)
Using fs As FileStream = File.OpenRead(templatePath)
Using ms As New MemoryStream
CopyStream(fs, ms)
Using doc As WordprocessingDocument = WordprocessingDocument.Open(ms, True)
'update the document
doc.MainDocumentPart.Document.Save()
End Using
End Using
End Using
End Sub
Private Sub CopyStream(source As Stream, target As Stream)
Dim buffer() As Byte
Dim bytesRead As Integer = 1
ReDim buffer(32768)
While bytesRead > 0
bytesRead = 0
bytesRead = source.Read(buffer, 0, buffer.Length)
target.Write(buffer, 0, bytesRead)
End While
End Sub
This works for normal updates of content controls etc. and document is fine when streamed back to client or saved as docx. But it corrupts doc when inserting an AltChunk.
Opening a doc from a physical file path works when inserting AltChunk like so:
Using doc As WordprocessingDocument = WordprocessingDocument.Open(strTempFile, True)
Dim altChunkId As String = "AltChunkId1"
Dim mainDocPart As MainDocumentPart = doc.MainDocumentPart
Dim chunk As AlternativeFormatImportPart = mainDocPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.Xhtml,
altChunkId)
Dim strHTML As String = "<html><head/><body><h1>Html Heading</h1><p>This is an html document in a string literal.</p></body></html>"
Using chunkStream As Stream = chunk.GetStream(FileMode.Create, FileAccess.Write)
Using sr As StreamWriter = New StreamWriter(chunkStream)
sr.Write(strHTML)
End Using
End Using
Dim altChunk As New AltChunk
altChunk.Id = altChunkId
mainDocPart.Document.Body.InsertAfter(altChunk, mainDocPart.Document.Body.Elements(Of Paragraph)().Last())
mainDocPart.Document.Save()
End Using
It seems you cannot import an AltChunk into a memory stream, you can only do it when you open the physical file for writing. Can anyone shed some light on this matter?
I know this is an old post, but i have the same issue.
When using AltChunk in file, it works but not when in MemoryStream.
It would be great if anyone knows anything about this. This is how i initiate the WordprocessingDocument
var byteArrayWithFileFrom360 = ProcessFileHandler.GetFileContent(204735);
var wordDocMemoryStream = new MemoryStream();
wordDocMemoryStream.Write(byteArrayWithFileFrom360, 0, byteArrayWithFileFrom360.Length);
var myDoc = WordprocessingDocument.Open(wordDocMemoryStream, true);