c # openxml: скопировать абзац со шрифтом и выравниванием - PullRequest
0 голосов
/ 29 марта 2019

Я хочу скопировать часть слова * .docx в другой файл * .docx.Для этого я получаю список абзацев из исходного файла:

private static List<Paragraph> getTextItems( string origFile )
{
    List<Paragraph> paragraphItems = new List<Paragraph>();
    var parser = new LineTextParser();

    using (var doc = WordprocessingDocument.Open( origFile, false))
    {

        foreach (var el in doc.MainDocumentPart.Document.Body.Elements().OfType<Paragraph>())
        {
            if (parser.isHorizontalTableLine(el.InnerText))
            {
                if (true == el.InnerText.EndsWith("|"))
                {
                    break;
                }
            }
            paragraphItems.Add(el);
        }
    }

    return paragraphItems;
}

Затем я пытаюсь применить эти элементы к новому файлу:

    using (WordprocessingDocument wordDocument =
        WordprocessingDocument.Create(resultFile, WordprocessingDocumentType.Document))
    {
        // Add a main document part. 
        MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();

        // Create the document structure and add some text.
        mainPart.Document = new Document();
        Body body = mainPart.Document.AppendChild(new Body());
        foreach (var item in paragraphItems)
        {
            Paragraph para = body.AppendChild(new Paragraph() );
            para.Append(item.ParagraphProperties.CloneNode(true));
            Run run = para.AppendChild(new Run());
            run.AppendChild(new Text(item.InnerText));
        }
    }

Но оригинальное форматирование потеряно- Я имею в виду, что шрифт был изменен, а также выравнивание.Какое здесь решение?

1 Ответ

0 голосов
/ 29 марта 2019

Сначала вместо item.InnerText используйте item.InnerXml и установите новый абзац Xml в исходный абзац Xml.

Вам просто нужно изменить порядок добавления абзацев к документу. Приведенный ниже метод должен создать файл с абзацами, скопированными из исходного документа.

public void CreateFile(string resultFile, List<Paragraph> paragraphItems)
{
    using (WordprocessingDocument wordDocument =
           WordprocessingDocument.Create(resultFile, WordprocessingDocumentType.Document))
    {
        MainDocumentPart mainPart = wordDocument.AddMainDocumentPart();

        mainPart.Document = new Document();
        Body body = mainPart.Document.AppendChild(new Body());

        foreach (var item in paragraphItems)
        {
            Paragraph para = new Paragraph();

            // set the inner Xml of the new paragraph
            para.InnerXml = item.InnerXml;

            // append paragraph to body here
            body.AppendChild(para);
        }
    }
}

Теперь нам нужно применить стили из doc.MainDocumentPart.StyleDefinitionsPart к новому документу.

Этот следующий метод был изменен из этого руководства MSDN . Извлекает стили из StyleDefinitionsPart как XDocument.

public XDocument ExtractStylesPart(string sourceFile)
{
    XDocument styles = null;

    // open readonly
    using (var document = WordprocessingDocument.Open(sourceFile, false))
    {
        var docPart = document.MainDocumentPart;

        StylesPart stylesPart = docPart.StyleDefinitionsPart;

        if (stylesPart != null)
        {
            using (var reader = XmlNodeReader.Create(
                       stylesPart.GetStream(FileMode.Open, FileAccess.Read)))
            {
                // Create the XDocument.
                styles = XDocument.Load(reader);
            }
        }
    }
    // Return the XDocument instance.
    return styles;
} 

Затем вам нужно сохранить стиль в новом документе. Следующий метод должен работать для вас:

public void SetStyleToTarget(string targetFile, XDocument newStyles)
{
    // open with write permissions
    using (var doc = WordprocessingDocument.Open(targetFile, true))
    {
            // add or get the style definition part
            StyleDefinitionsPart styleDefn = null;
            if (doc.MainDocumentPart.StyleDefinitionsPart == null)
            {
                styleDefn = doc.MainDocumentPart.AddNewPart<StyleDefinitionsPart>();
            }
            else
            {
                styleDefn = doc.MainDocumentPart.StyleDefinitionsPart;
            }

        // populate part with the new styles
        if (styleDefn != null)
        {
            // write the newStyle xDoc to the StyleDefinitionsPart using a streamwriter
            newStyles.Save(new StreamWriter(
                           styleDefn.GetStream(FileMode.Create, FileAccess.Write)));
        }
        // probably not needed (works for me with or without this save)
        doc.Save();
    }
}

Вышеупомянутый метод был вдохновлен путеводителем, связанным ранее. Разница в том, что это создает новый элемент стиля для нового документа (потому что у него его нет - мы только что создали документ).

Я использовал только StyleDefinitionsPart, но есть другая часть StylesWithEffectsPart. Возможно, вам придется реализовать аналогичный метод для StylesWithEffectsPart, если ваш документ использует его.

...