C# 无法在Open Xml中使用现有段落样式

C# 无法在Open Xml中使用现有段落样式,c#,ms-word,openxml,openxml-sdk,word-2010,C#,Ms Word,Openxml,Openxml Sdk,Word 2010,我正在将一个HTML文件导出到一个打开的XML Word文件。如果在HTML中使用了,我想向该部分添加Heading1样式。但不知何故,当我在MicrosoftWord2010中打开文档时,该样式没有被应用 如果我在Libre Office中打开创建的文档,则会应用某些样式 我自己也定义了一些风格,如果我使用其中的一种风格,Word和Libre Office中的一切都很顺利 我打开了适用于Microsoft Office的Open XML SDK 2.5生产力工具,当我查看它提供的示例代码时,它

我正在将一个HTML文件导出到一个打开的XML Word文件。如果在HTML中使用了
,我想向该部分添加Heading1样式。但不知何故,当我在MicrosoftWord2010中打开文档时,该样式没有被应用

如果我在Libre Office中打开创建的文档,则会应用某些样式

我自己也定义了一些风格,如果我使用其中的一种风格,Word和Libre Office中的一切都很顺利

我打开了适用于Microsoft Office的Open XML SDK 2.5生产力工具,当我查看它提供的示例代码时,它建议:

ParagraphStyleId paragraphStyleId1=新的ParagraphStyleId(){Val=“Kop1”}

Kop1(而不是Heading1)是因为我的单词是荷兰语,所以我的模板是荷兰语的,但这并没有解决问题

在这个代码示例中,我创建了段落并添加了样式和文本:

using (wordDocument = WordprocessingDocument.Open(documentStream, true)) 
{
    MainDocumentPart mainPart = wordDocument.MainDocumentPart;
    WP.Body body = wordDocument.MainDocumentPart.Document.Body;
    WP.Paragraph para = body.AppendChild(new WP.Paragraph());
    StyleDefinitionsPart part = wordDocument.MainDocumentPart.StyleDefinitionsPart;
    if (part != null)
    {
        WP.ParagraphProperties pPr = new WP.ParagraphProperties();
        WP.ParagraphStyleId paragraphStyleId1 = new WP.ParagraphStyleId() { Val = "Heading1" };
        pPr.Append(paragraphStyleId1);

        para.Append(pPr);
    }

    WP.Run run = para.AppendChild(new WP.Run());
    run.AppendChild(new WP.Text(value));
}
它定义了样式,因为我使用的是模板,所以代码将包含在if语句中

我还尝试了它的风格标题(荷兰语titel),两种都试了,但都不起作用

我真的不明白出了什么问题,为什么我可以使用自己创建的样式,但是不能使用预定义的Word样式,我没有在模板中删除该样式

它不知怎么地不识别预定义的样式

编辑/添加


我让它工作,但不是我想要的方式,我必须点击模板文档中的预定义样式,然后保存文档。不知何故,在单击它们并保存后,这些样式会添加到文档中,因为如果我现在使用模板生成最终文档,我可以使用这些样式。
但是如果不先单击文档中的样式,我就无法使用它们,因为它们没有保存?

不幸的是,这种情况会发生,因为默认情况下,该样式没有写入文档(即使它是Word的“内置”样式),因此不应用该样式

如果通过代码创建文档,然后通过Word创建另一个应用了Heading1样式的文档,然后比较\Word\styles.XML中的XML,您将看到Word生成的XML中还有一个附加部分:

您可以使用以下代码生成自己的样式信息。除了硬编码,我不知道如何从其他地方获取这些样式;也许它们可以在某个地方的dotx文件中找到请参阅下面的编辑以了解更多信息

using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(documentStream, true))
{
    MainDocumentPart mainPart = wordDocument.MainDocumentPart;
    Body body = wordDocument.MainDocumentPart.Document.Body;
    Paragraph para = body.AppendChild(new Paragraph());
    StyleDefinitionsPart part = wordDocument.MainDocumentPart.StyleDefinitionsPart;
    if (part != null)
    {
        Style style = new Style()
        {
            Type = StyleValues.Paragraph,
            StyleId = "Heading1",
            BasedOn = new BasedOn() { Val = "Normal" },
            NextParagraphStyle = new NextParagraphStyle() { Val = "Normal" }
        };

        StyleName styleName1 = new StyleName() { Val = "heading 1" };
        style.Append(styleName1);
        style.Append(new PrimaryStyle());
        StyleRunProperties styleRunProperties1 = new StyleRunProperties();
        styleRunProperties1.Append(new Bold());
        styleRunProperties1.Append(new RunFonts() 
            {
                ComplexScriptTheme=ThemeFontValues.MajorBidi, 
                HighAnsiTheme=ThemeFontValues.MajorHighAnsi,
                EastAsiaTheme=ThemeFontValues.MajorEastAsia, 
                AsciiTheme=ThemeFontValues.MajorAscii 
            });
        styleRunProperties1.Append(new FontSize() { Val = "28" });
        styleRunProperties1.Color = new Color() 
            {
                Val = "365F91",
                ThemeShade = "BF",
                ThemeColor = ThemeColorValues.Accent1
            };
        style.Append(styleRunProperties1);
        part.Styles.Append(style);

        ParagraphProperties pPr = new ParagraphProperties();
        ParagraphStyleId paragraphStyleId1 = new ParagraphStyleId() { Val = "Heading1" };
        pPr.Append(paragraphStyleId1);
        para.Append(pPr);
    }

    Run run = para.AppendChild(new Run());
    run.AppendChild(new Text("This is a heading"));
}
编辑

我查看了一下,发现单词default样式确实存储在.dotx文件中,正如我上面猜测的那样。这些文件也可以通过OpenXMLAPI读取,因此可以将样式从那里复制到文档中。这方面的代码与我们已有的代码非常相似,增加了读取Default.dotx文件并从中获取样式的功能

在我的系统上,dotx文件的格式是C:\Program files\Microsoft Office\Office14\1033\QuickStyles,我在下面硬编码过。我不知道是否有地方可以动态获取(可能是注册表),但如果没有,我想配置文件就足够了

using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(documentStream, true))
{
    MainDocumentPart mainPart = wordDocument.MainDocumentPart;
    Body body = wordDocument.MainDocumentPart.Document.Body;
    Paragraph para = body.AppendChild(new Paragraph());
    Paragraph para2 = body.AppendChild(new Paragraph());
    Paragraph para3 = body.AppendChild(new Paragraph());

    StyleDefinitionsPart part = wordDocument.MainDocumentPart.StyleDefinitionsPart;
    if (part != null)
    {
        //I'm looping the styles and adding them here
        //you could clone the whole StyleDefinitionsPart
        //but then you'd lose custom styles in your source doc
        using (WordprocessingDocument wordTemplate = WordprocessingDocument.Open(@"C:\Program Files\Microsoft Office\Office14\1033\QuickStyles\default.dotx", false))
        {
            foreach (var templateStyle in wordTemplate.MainDocumentPart.StyleDefinitionsPart.Styles)
            {
                part.Styles.Append(templateStyle.CloneNode(true));
            }
        }

        //I can now use any built in style 
        //I'm using Heading1, Title and IntenseQuote as examples
        //You may need to do a language conversion here as 
        //you mentione your docx is in Dutch
        ParagraphProperties pPr = new ParagraphProperties();
        ParagraphStyleId paragraphStyleId1 = new ParagraphStyleId() { Val = "Heading1" };
        pPr.Append(paragraphStyleId1);
        para.Append(pPr);

        Run run = para.AppendChild(new Run());
        run.AppendChild(new Text("This is a heading"));

        ParagraphProperties pPr2 = new ParagraphProperties();
        ParagraphStyleId paragraphStyleId2 = new ParagraphStyleId() { Val = "Title" };
        pPr2.Append(paragraphStyleId2);
        para2.Append(pPr2);

        Run run2 = para2.AppendChild(new Run());
        run2.AppendChild(new Text("This is a title"));

        ParagraphProperties pPr3 = new ParagraphProperties();
        ParagraphStyleId paragraphStyleId3 = new ParagraphStyleId() { Val = "IntenseQuote" };
        pPr3.Append(paragraphStyleId3);
        para3.Append(pPr3);

        Run run3 = para3.AppendChild(new Run());
        run3.AppendChild(new Text("This is an intense quote"));
    }
}
此生成的文件如下所示:


为了澄清,生产力工具将您的
Heading1
样式名称显示为
Kop1
,您已经尝试在实际代码中使用它,即
WP.ParagraphStyleId paragraphStyleId1=new WP.ParagraphStyleId(){Val=“Kop1”}?您是否可以在发布实际文档(生成的,而不是模板)的反映时,仅在中添加一个标题,同时实际使用word打开模板文件并保存相同类型的文档(仅在中添加一个标题)我确实试过使用
WP.ParagraphStyleId paragraphStyleId1=newwp.ParagraphStyleId(){Val=“Kop1”}我还反映了您所建议的文件,并且在我用Word创建的文档中添加了样式:`,而在生成的文档中却没有。但我不明白,因为这是我可以在Word中选择的默认样式。还有两个问题-什么是
documentStream
这是一个
文件。打开模板docx的
?另外,在
StyleDefinitionsPart部分=wordDocument.MainDocumentPart.StyleDefinitionsPart零件包含什么?编辑-我刚刚用我的一个模板尝试了你的代码,它工作得很好,所以我们这里肯定有一个样式名称/文档类型问题。文档流是一个保存文档的memoryStream。首先,我打开templateDocument并将其另存为docuementStream。之后,我可以添加我想要的所有内容,并最终转换流,以便将其作为附件下载。
styleDefinitionsPart
部分包含文档的所有样式。因为如果我不使用模板而是使用空文档,那么文档中就没有StyleDefinitionsPart,应该创建它。我将使用新模板重试,可能模板文件中有问题..我已使其正常工作,但不是我想要的方式,我必须先在word模板中选择标题1(Kop1),然后保存模板。之后,如果我使用此模板生成文档,它将使用Heading1(Kop1)样式。因此,Word中预定义的样式不会直接保存在styles.xml中,而是在选择它们之后才保存?我确实找到了额外的样式,我已经在其中一条注释中提到过。。我真的不想硬编码这些“标准”样式,因为它们在Word中可用,但遗憾的是这些默认样式在默认情况下没有写入文档。谢谢你的反应,我会自己创造风格。对不起,我没有看到你最后的评论。当然,这是另一种方法;在源文件中使用该样式,则该样式将存在于styles.xml中,您无需创建即可引用该样式