0

I'm not the greatest at Open Office XML and have been struggling to try to add an image to a docx file I am generating programatically in C# / ASP.Net. I'm trying to put a logo on top of resume text block. I had the program working fine when I was only working with the main text part (resumeText), but when I added the code to try to add the image, I'm getting an error "The file '..'.docx cannot be opened because there are problems with the contents. Then the details say 'Undeclared prefix'. I thought I had copied the xml correctly from another example but can't seem to get it to work. Can anyone see where I'm going wrong? Thanks for any help anyone can provide. Here is the relevant code :

protected void ibtDownload_Click(object sender, ImageClickEventArgs e)
{
    string attachmentDir = "~/tempDwnlds/";
    string fileName = m_candidateUser.firstName + "_" + m_candidateUser.lastName + "_" + m_candidateUser.userID.ToString().Substring(0, 6);
    string imagesPath = Server.MapPath("Images/Logo1.jpg");
    CreateNewWordDocument(Server.MapPath(attachmentDir) + fileName + ".docx", Server.HtmlEncode(m_candidate.resume), imagesPath);       
}


public static void CreateNewWordDocument(string document, string resumeText, string imagesPath)
{
    using (WordprocessingDocument wordDoc = WordprocessingDocument.Create(document, WordprocessingDocumentType.Document))
    {
        // Set the content of the document so that Word can open it.
        MainDocumentPart mainPart = wordDoc.AddMainDocumentPart();
        ImagePart newImage = wordDoc.MainDocumentPart.AddImagePart("images/jpeg");
        using (Stream image = new FileStream(imagesPath, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            newImage.FeedData(image);
        }
        SetMainDocumentContent(mainPart, resumeText, imagesPath);
    }
}

// Set the content of MainDocumentPart.
public static void SetMainDocumentContent(MainDocumentPart part, string resumeText, string imagesPath)
{

    string docXml =
     @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?> 
<w:document xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
    <w:body>
        <w:p>
          <w:r>
            <w:drawing>
              <wp:inline>
                <wp:extent cx=""3200400"" cy=""704850"" /> <!-- describes the size of the image -->
                <wp:docPr id=""2"" name=""Picture 1"" descr=""filename.JPG"" />
                <a:graphic>
                  <a:graphicData uri=""http://schemas.openxmlformats.org/drawingml/2006/picture"">
                    <pic:pic>
                      <pic:nvPicPr>
                        <pic:cNvPr id=""0"" name=""filename.JPG"" />
                        <pic:cNvPicPr />
                      </pic:nvPicPr>
                      <pic:blipFill>
                        <a:blip r:embed=""" + imagesPath + @""" /> <!-- this is the ID you need to find -->
                        <a:stretch>
                          <a:fillRect />
                        </a:stretch>
                      </pic:blipFill>
                      <pic:spPr>
                        <a:xfrm>
                          <a:ext cx=""3200400"" cy=""704850"" />
                        </a:xfrm>
                        <a:prstGeom prst=""rect"" />
                      </pic:spPr>
                    </pic:pic>
                  </a:graphicData>
                </a:graphic>
              </wp:inline>
            </w:drawing>
          </w:r>
        </w:p>
        <w:p>
            <w:r>
                <w:t xml:space='preserve'>" + WrappableDocXText(resumeText) + @"</w:t>
            </w:r>
        </w:p>
    </w:body>
</w:document>";

    using (Stream stream = part.GetStream())
    {
        byte[] buf = (new UTF8Encoding()).GetBytes(docXml);
        stream.Write(buf, 0, buf.Length);
    }
}

public static string WrappableDocXText(string source)
{
    string nwln = Environment.NewLine;
    return source.Replace(nwln, "<w:br/>");
}

1 Answer 1

1

RelationshipId should be there instead of imagesPath @ <a:blip r:embed=""" + imagesPath + @""" /> which you can get as string relationshipId = mainPart.GetIdOfPart(imagePart)

You can find the sample code @ msdn link How to Insert an Picture to Word Processing Document

UPDATE: You need to make changes at two places 1) Pass id of image part as displayed below SetMainDocumentContent(mainPart, resumeText, mainPart.GetIdOfPart(newImage));

2) Add namesspaces as displayed below

public static void SetMainDocumentContent(MainDocumentPart part, string resumeText, string relId) {

        string docXml =   @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?><w:document xmlns:a=""http://schemas.openxmlformats.org/drawingml/2006/main"" xmlns:pic=""http://schemas.openxmlformats.org/drawingml/2006/picture"" xmlns:a14=""http://schemas.microsoft.com/office/drawing/2010/main"" xmlns:wpc=""http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas"" xmlns:mc=""http://schemas.openxmlformats.org/markup-compatibility/2006"" xmlns:r=""http://schemas.openxmlformats.org/officeDocument/2006/relationships"" xmlns:m=""http://schemas.openxmlformats.org/officeDocument/2006/math"" xmlns:wp14=""http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing"" xmlns:wp=""http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"" xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"" xmlns:w14=""http://schemas.microsoft.com/office/word/2010/wordml"" xmlns:wpg=""http://schemas.microsoft.com/office/word/2010/wordprocessingGroup"" xmlns:wpi=""http://schemas.microsoft.com/office/word/2010/wordprocessingInk"" xmlns:wne=""http://schemas.microsoft.com/office/word/2006/wordml"" xmlns:wps=""http://schemas.microsoft.com/office/word/2010/wordprocessingShape"">    <w:body>
    <w:p>
      <w:r>
        <w:drawing>
          <wp:inline >
            <wp:extent cx=""3200400"" cy=""704850"" /> <!-- describes the size of the image -->
            <wp:docPr id=""2"" name=""Picture 1"" descr=""filename.JPG"" />
            <a:graphic>
              <a:graphicData uri=""http://schemas.openxmlformats.org/drawingml/2006/picture"">
                <pic:pic>
                  <pic:nvPicPr>
                    <pic:cNvPr id=""0"" name=""filename.JPG"" />
                    <pic:cNvPicPr />
                  </pic:nvPicPr>
                  <pic:blipFill>
                    <a:blip r:embed=""" + relId + @""" /> <!-- this is the ID you need to find -->
                    <a:stretch>
                      <a:fillRect />
                    </a:stretch>
                  </pic:blipFill>
                  <pic:spPr>
                    <a:xfrm>
                      <a:ext cx=""3200400"" cy=""704850"" />
                    </a:xfrm>
                    <a:prstGeom prst=""rect"" />
                  </pic:spPr>
                </pic:pic>
              </a:graphicData>
            </a:graphic>
          </wp:inline>
        </w:drawing>
      </w:r>
    </w:p>
    <w:p>
        <w:r>
            <w:t xml:space='preserve'>" + WrappableDocXText(resumeText) + @"</w:t>
        </w:r>
    </w:p>
</w:body>

";

        using (Stream stream = part.GetStream())
        {
            byte[] buf = (new UTF8Encoding()).GetBytes(docXml);
            stream.Write(buf, 0, buf.Length);
        }
    }
Sign up to request clarification or add additional context in comments.

6 Comments

thank you very much Atul... the only issue with that code is that it shows how to insert an image but not an image AND text which I need. Sorry but I'm just confused about the MainPart. Does the ImagePart have to be added to that? If so, then how do I set the text? Thanks for your help!
I also tried to just add the line of code you gave to get the relationshipId and replaced the imagesPath with that but I had the same result.
You need to make changes at 2 places ... Edited my answer
Hi Atul.... thank you SSOOOOO MUCH!!! How can I ever repay you? The code I had was causing me headaches so I actually used the Reflector tool to give me the exact code I needed. But your suggestion to add the ImagePart and then get the RelationshipID and replace the 'embed' with it worked perfectly!! Thank you again so much! I would post the whole solution but don't have the rights.
I just saw the updated post you put where you added the namespaces. The Reflector tool had given me all of those too. Thanks again.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.