OpenXML SDK: встроенный объект OLE сжимается после редактирования

Я должен создать очень большой документ Word, который содержит много графиков (да, это должен быть Word). Графики создаются сторонним приложением. Поскольку стороннее приложение поддерживает только документы Word, размер которых меньше 8 МБ, а документы, которые мне нужно сгенерировать, гораздо больше, я строю изображения для отдельных документов, по одному, затем извлекаю их и добавляю в окончательный документ.

Используемый ими "формат изображения" - это нечто запатентованное, встроенное через OLE. Двойной щелчок открывает приложение в фоновом режиме, которое позволяет масштабировать и панорамировать изображение. Теперь, выходя из этого графического редактора, картинка внезапно сжимается, разрушая макет документа. Оригинальный документ, из которого я извлекаю изображение, не демонстрирует такого поведения.

В настоящее время я занимаюсь:

  1. Разместите изображение во временном документе, пусть оно будет temp.docx
  2. Открой temp.docx как WordprocessingDocument
  3. Извлечь проприетарные данные двоичного изображения, пусть это будет plot.bin
  4. Извлеките его представление WMF, пусть plot.wmf
  5. Поиск соответствующего Shape объект, создать клон его Shapetype ребенок
  6. Добавить plot.bin как EmbeddedObjectPart
  7. Добавить plot.wmf как ImagePart
  8. Создать Shape с ImageData ребенок ссылается на идентификатор plot.wmf
  9. Создать OleObject
  10. Добавьте картинку к абзацу EmbeddedObject часть

Когда я смотрю на генерируемый 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 ответов

Другие вопросы по тегам