Программное редактирование DOCX документа в .NET

Категория: Office.NET

26 декабря 2022

VintaSoft Imaging .NET SDK в комбинации с VintaSoft Office .NET Plug-in предоставляет функционал для программного редактирования DOCX документов, т.е. SDK не позволяет создать новый DOCX документ, но может отредактировать существующий DOCX документ.

Для редактирования существующего DOCX документа используется класс DocxDocumentEditor, который предоставляет следующие программные возможности:

Возможность редактирования DOCX документа была реализована специально для ускорения процесса создания генераторов отчетов (прайс листов) в векторных (PDF, SVG) или растовых (PNG, TIFF,…) форматах. Преимуществом хранения шаблона отчета в виде DOCX документа являются богатые возможности разметки DOCX документа и простота создания DOCX документа с помощью MS Word или OpenOffice.

Для генерации отчета в виде PDF документа нужно выполнить следующие шаги:
  1. Создать шаблон документа в виде DOCX документа с помощью MS Word или OpenOffice.
  2. Изменить данные в шаблоне и сохранить измененный документ в новый DOCX файл используя класс DocxDocumentEditor.
  3. Сконвертировать созданный DOCX документ в PDF документ используя VintaSoft PDF .NET Plug-in.

Подробнее о создании генератора отчетов или прайс листов расказанно в статье Создание PDF генератора счетов в .NET.

Следующий пример демонстрирует как можно отредактировать контент существующего DOCX документа:

// The project, which uses this code, must have references to the following assemblies:
// - Vintasoft.Shared
// - Vintasoft.Imaging
// - Vintasoft.Imaging.Office.OpenXml

// Edits the DOCX document
public static void EditDocx(string templateFilename, string outFilename)
{
    using (Vintasoft.Imaging.Office.OpenXml.Editor.DocxDocumentEditor documentEditor =
        new Vintasoft.Imaging.Office.OpenXml.Editor.DocxDocumentEditor(templateFilename))
    {
        Generate(documentEditor);

        documentEditor.Save(outFilename);
    }
}

// Generates DOCX document using DOCX document editor
public static void Generate(Vintasoft.Imaging.Office.OpenXml.Editor.DocxDocumentEditor documentEditor)
{
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlDocumentElement documentBody = documentEditor.Body;
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlDocumentTable[] documentTables = documentEditor.Tables;

    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties grayTextProperties = 
        new Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties();
    grayTextProperties.Color = System.Drawing.Color.Gray;

    // set Headers and Footers
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlDocumentElement header = documentEditor.CreateHeader();
    header.Text = string.Format("VintaSoft Office .NET Plugin, DOCX Editor Example. {0}", System.DateTime.Now);
    header.SetTextProperties(grayTextProperties);
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlDocumentElement footer = documentEditor.CreateFooter();
    footer.Text = "VintaSoft Imaging .NET SDK";
    footer.SetTextProperties(grayTextProperties);
    footer.SetTextProperties(Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties.BoldText);
    documentEditor.SetHeaderFooterConfiguration(header, footer);

    //
    // 1. Text replace.
    //

    // replace first occurrence
    documentBody["[field1]"] = "value1";

    // replace all occurrences
    documentBody.ReplaceText("[field2]", "value2");

    // get text content that corresponds to the [field3] and set text
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextContent field3Content = documentBody.FindText("[field3]");
    field3Content.Text = "value3";

    // replace field to the multiline text
    documentBody["[multiline_field]"] = "\nline1\nline2\nline3";


    //
    // 2. Change text properties.
    //

    // set text color
    documentBody.FindText("COLOR").Substring(0, 2).SetTextProperties(CreateColorTextProperties(System.Drawing.Color.Red));
    documentBody.FindText("COLOR").Substring(2, 1).SetTextProperties(CreateColorTextProperties(System.Drawing.Color.Green));
    documentBody.FindText("COLOR").Substring(3, 2).SetTextProperties(CreateColorTextProperties(System.Drawing.Color.Blue));

    // highlight text
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties highlightedTextProperties = 
        new Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties();
    highlightedTextProperties.Highlight = Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextHighlightType.Green;
    documentBody.FindText("highlighted text").SetTextProperties(highlightedTextProperties);

    // set text "bold text" as bold text
    documentBody.FindText("bold text").SetTextProperties(Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties.BoldText);

    // set text "italic text" as italic text
    documentBody.FindText("italic text").SetTextProperties(Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties.ItalicText);

    // set text "underline text" as underline text
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties underlineTextProperties =
        new Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties();
    underlineTextProperties.Underline = Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextUnderlineType.Single;
    underlineTextProperties.UnderlineColor = System.Drawing.Color.Red;
    documentBody.FindText("underline text").SetTextProperties(underlineTextProperties);

    // set text "strike text" as striked out text
    documentBody.FindText("strike text").SetTextProperties(Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties.StrikeText);

    // change font size
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties setTextSize = 
        new Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties();
    setTextSize.FontSize = 16;
    documentBody.FindText("text with size 16pt").Substring(0, 4).SetTextProperties(setTextSize);

    // change text style
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties setTextStyle = 
        new Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties();
    setTextStyle.Style = documentEditor.Styles.FindByName("RedStyle");
    documentBody.FindText("RedStyle").SetTextProperties(setTextStyle);

    // change character spacing
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties setCharacterSpacing = 
        new Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties();
    setCharacterSpacing.CharacterSpacing = 2;
    documentBody.FindText("spacing is 2pt").FindText("spacing").SetTextProperties(setCharacterSpacing);
    setCharacterSpacing.CharacterSpacing = -1;
    documentBody.FindText("spacing is -1pt").FindText("spacing").SetTextProperties(setCharacterSpacing);

    // change character horizontal scaling
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties setCharacterHorizontalScaling = 
        new Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties();
    setCharacterHorizontalScaling.CharacterHorizontalScaling = 0.5f;
    documentBody.FindText("horizontal scaling is 0.5").FindText("horizontal scaling").SetTextProperties(setCharacterHorizontalScaling);
    setCharacterHorizontalScaling.CharacterHorizontalScaling = 2;
    documentBody.FindText("horizontal scaling is 2").FindText("horizontal scaling").SetTextProperties(setCharacterHorizontalScaling);

    //
    // 3. Change paragraph properties.
    //
    // set paragraph justification
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlParagraphProperties justificationParagraphProperties = 
        new Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlParagraphProperties();
    justificationParagraphProperties.Justification = Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlParagraphJustification.Left;
    documentBody.FindText("Left Justification").SetParagraphProperties(justificationParagraphProperties);
    justificationParagraphProperties.Justification = Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlParagraphJustification.Center;
    documentBody.FindText("Center Justification").SetParagraphProperties(justificationParagraphProperties);
    justificationParagraphProperties.Justification = Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlParagraphJustification.Right;
    documentBody.FindText("Right Justification").SetParagraphProperties(justificationParagraphProperties);

    // set paragraph properties
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlParagraphProperties indentationParagraphProperties = 
        new Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlParagraphProperties();
    indentationParagraphProperties.SpacingBeforeParagraph = 10;
    indentationParagraphProperties.FirstLineIndentation = 50;
    indentationParagraphProperties.RightIndentation = 50;
    indentationParagraphProperties.LeftIndentation = 100;
    indentationParagraphProperties.FillColor = System.Drawing.Color.LightBlue;
    indentationParagraphProperties.Justification = Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlParagraphJustification.Both;
    documentBody.FindText("This paragraph has left indentation 100pt").SetParagraphProperties(indentationParagraphProperties);

    //
    // 4. Copy table row
    //

    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlDocumentTable table = documentTables[0];
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlDocumentTableRow templateRow = table[1];
    System.Drawing.Color[] colors = new System.Drawing.Color[] { System.Drawing.Color.Red, System.Drawing.Color.Green, 
        System.Drawing.Color.Blue, System.Drawing.Color.Orange, System.Drawing.Color.Yellow };
    for (int i = 0; i < colors.Length; i++)
    {
        // insert copy of template row before template row
        Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlDocumentTableRow rowCopy = 
            (Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlDocumentTableRow)templateRow.InsertCopyBeforeSelf();

        // set row data
        rowCopy[0].Text = string.Format("Copy {0} ({1})", i, colors[i]);
        rowCopy["[cell1]"] = string.Format("cell data {0}", i);

        // set cell colors
        rowCopy[1].SetFillColor(colors[i]);
        rowCopy[2].SetFillColor(colors[i]);

        // if color has odd index in colors array
        if ((i % 2) == 1)
        {
            // set row height to 10mm
            rowCopy.Height = Vintasoft.Imaging.Utils.UnitOfMeasureConverter.ConvertToPoints(10, Vintasoft.Imaging.UnitOfMeasure.Millimeters);
        }
    }

    // remove template row
    templateRow.Remove();


    //
    // 5. Copy table border properties from another table.
    //

    // get cell border templates
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlDocumentTable bordersTemplateTable = 
        documentTables[1];
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlDocumentTableCell boldBorderTemplate =
        bordersTemplateTable.FindCell("[bold]");
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlDocumentTableCell colorBorderTemplate = 
        bordersTemplateTable.FindCell("[color]");

    // remove border template table
    bordersTemplateTable.Remove();

    // get test table
    table = documentTables[2];

    // set borders from template cells
    table.FindRow("[bold_row]").SetBorder(boldBorderTemplate);
    table.FindCell("[bold_cell]").SetBorder(boldBorderTemplate);
    table.FindRow("[color_row]").SetBorder(colorBorderTemplate);
    table.FindCell("[color_cell]").SetBorder(colorBorderTemplate);

    // set outside border inside table
    table.SetOutsideBorder(table.FindCell("[bold_first]"), table.FindCell("[bold_last]"), boldBorderTemplate);

    //
    // 6. Set hyperlink in text.
    //
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextContent hyperlinkTextContent = documentBody.FindText("VintaSoft Web Site");
    documentEditor.SetHyperlink(hyperlinkTextContent, "https://www.vintasoft.com");
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties hyperlinkTextProperties = 
        new Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties();
    hyperlinkTextProperties.IsUnderline = true;
    hyperlinkTextProperties.Color = System.Drawing.Color.Blue;
    hyperlinkTextContent.SetTextProperties(hyperlinkTextProperties);

    //
    // 7. Change and delete image.
    //

    // find image after text "image must be inverted:"
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlDocumentImage imageElement =
        documentBody.FindText("image must be inverted:").FindAfter<Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlDocumentImage>();
    // gets as VintasoftImage from image element
    using (Vintasoft.Imaging.VintasoftImage image = imageElement.GetImage())
    {
        // invert image
        Vintasoft.Imaging.ImageProcessing.Color.InvertCommand invert = 
            new Vintasoft.Imaging.ImageProcessing.Color.InvertCommand();
        invert.ExecuteInPlace(image);

        // set image of image element as new resource
        imageElement.SetImage(image, true);
    }

    // remove image that is located after "image must be deleted:" text
    documentBody.FindText("image must be deleted:").FindAfter<Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlDocumentImage>().Remove();
}

// Creates the color text properties
private static Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties CreateColorTextProperties(System.Drawing.Color color)
{
    Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties result = 
        new Vintasoft.Imaging.Office.OpenXml.Editor.OpenXmlTextProperties();
    result.Color = color;
    return result;
}