简体   繁体   中英

Adding ImagePart to docx in ASP.Net C# Open Office XML

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/>");
}

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);
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM