OpenXML SDK:编辑

时间:2016-09-27 15:08:41

标签: c# openxml openxml-sdk

我必须创建一个包含大量图表的非常大的Word文档(是的,它必须是Word)。这些图由第三方应用程序生成。由于第三方应用程序仅支持小于8 MiB的Word文档,并且我必须生成的文档要大得多,因此我将图片绘制到单个文档中,每个文档一个,然后将它们提取出来,并将它们添加到我的最终文档中。 / p>

他们使用的“图片格式”是一些通过OLE嵌入的专有内容。双击它会在后台打开一个应用程序,允许在图片中进行缩放和平移。现在,当离开这个图片编辑器时,图片突然缩小,破坏了文档的布局。我从中提取图片的原始文档没有表现出这种行为。

目前,我所做的是:

  1. 将图片绘制到临时文档中,让它为temp.docx
  2. temp.docx打开为WordprocessingDocument
  3. 提取专有二进制图像数据,将其设为plot.bin
  4. 提取其WMF表示,让它为plot.wmf
  5. 搜索相应的Shape对象,创建其Shapetype孩子
  6. 的克隆
  7. plot.bin添加为EmbeddedObjectPart
  8. plot.wmf添加为ImagePart
  9. 创建一个Shape,其中ImageData孩子的ID为plot.wmf
  10. 创建OleObject
  11. 将图片添加为段落作为相应的EmbeddedObject部分
  12. 当我查看生成的XML时,它看起来与原始文档完全相同。

    以下是代码部分:

        /// <summary>
        /// Adds a picture
        /// </summary>
        /// <param name="doc">Document to add picture to</param>
        /// <param name="pictureFile">File with proprietary picture data</param>
        /// <param name="wmfRepresentationFile">WMF representation of the proprietary picture file</param>
        /// <param name="pictureNumber">A rising number of the embedded picture. Incremented upon
        /// embedding the picture!</param>
        private static void AddPicture(WordprocessingDocument doc,
                                       string pictureFile,
                                       string wmfRepresentationFile,
                                       Shapetype shapeType,
                                       ref int pictureNumber) {
            LOG.Debug("Embedding the picture in the document");
            var emObj = doc.MainDocumentPart.AddEmbeddedObjectPart("application/vnd.openxmlformats-officedocument.oleObject");
            using (var pictureIn = new FileStream(pictureFile, FileMode.Open, FileAccess.Read, FileShare.Read))
            using (var oleOut = emObj.GetStream(FileMode.OpenOrCreate, FileAccess.Write)) {
                oleOut.Position = 0;
                pictureIn.CopyTo(oleOut);
                oleOut.Flush();
            }
            // An OLE embedded object also needs an image part.
            var image = doc.MainDocumentPart.AddImagePart(ImagePartType.Wmf);
            using (var imageIn = new FileStream(wmfRepresentationFile, FileMode.Open, FileAccess.Read, FileShare.Read))
            using (var imageOut = image.GetStream(FileMode.OpenOrCreate, FileAccess.Write)) {
                imageOut.Position = 0;
                imageIn.CopyTo(imageOut);
                imageOut.Flush();
            }
            // Get some IDs we need for the linking
            var objectPartId = doc.MainDocumentPart.GetIdOfPart(emObj);
            var objectId = ("_" + emObj.GetHashCode().ToString() + "000000").Substring(0, 11);
            var imagePartId = doc.MainDocumentPart.GetIdOfPart(image);
            // Create a new paragraph with the embedded object.
            // First, a "Shape"
            var shape = new Shape() {
                Id = "_x0000_i10" + pictureNumber,
                Style = "width:500.0pt;height:600.0pt", // Sets the size of the picture in the document
                Ole = new TrueFalseBlankValue(),
                Type = "#_x0000_t75",
            };
            // This must contain the "imagedata" - a link to the image representation of the
            // empty active picture
            shape.AppendChild(new ImageData() {
                Title = "",
                RelationshipId = imagePartId
            });
            // Now, the link to the active picture itself
            var ole = new OleObject() {
                Type = OleValues.Embed,
                ProgId = "Foo.Proprietary.Picture.1",
                ShapeId = "_x0000_i10" + pictureNumber,
                DrawAspect = OleDrawAspectValues.Content,
                ObjectId = objectId,
                Id = objectPartId
            };
            // Now, wrap everything into a Paragraph / Run / EmbeddedObject
            var pictureParagraph = new Paragraph(new Run(new EmbeddedObject(shapeType, shape, ole)));
            // And append it
            doc.MainDocumentPart.Document.Body.AppendChild(pictureParagraph);
            // Increase the image counter
            pictureNumber++;
        }
    

    我错过了什么/做错了什么?

0 个答案:

没有答案