使用 C# OpenXml SDK 为 MS Word 中的所有项目符号应用删除线
using C# OpenXml SDK apply strike through for all bullets in MS Word
我需要将样式应用于 MS Word
文档中的项目符号。
我可以使用 OpenXML
阅读完整的 docx
,然后使用 Run
节点
为段落应用样式
这就是我根据条件在其他区域应用样式的方式
private void StrikeAndUnderline(Run run)
{
if (run.RunProperties == null)
{
run.RunProperties = new RunProperties();
}
run.RunProperties.Strike = new Strike();
run.RunProperties.Strike.Val = true;
run.RunProperties.Underline = new Underline();
run.RunProperties.Underline.Val = UnderlineValues.Single;
}
但我没有得到 Run
属性 子弹
<w:p>
<w:pPr>
<w:pStyle w:val="ListParagraph"/>
<w:numPr>
<w:ilvl w:val="0"/>
<w:numId w:val="1"/>
</w:numPr>
</w:pPr>
<w:r>
<w:t>Paragraph one.</w:t>
</w:r>
</w:p>
不明显,但文档部分仅包含对存储在编号部分中的编号单元(具有所有格式和编号样式)的引用。
--文档部分。
所以在文档部分你必须grub NumberingLevelReference(w:ilvl) 和 NumberingId(w:numId).
--编号部分。
下一步是打开 Numbering 部分并搜索 NumberingInstance(w:num),其 NumberID 属性 与您在 Document 部分中看到的 NumberingId 相同。
现在,一旦您有了所需的 NumberingInstance,在它的子项中寻找 AbstractNumId 并记住它的值。
现在搜索具有您刚刚记住的相同 ID 的 AbstractNum 节点。
干杯!现在您拥有当前编号的属性。属性由编号级别分隔。所以现在搜索所需的 level(),即您在文档部分的编号属性中看到的那个。
一旦找到表示正确编号级别的节点,您应该将其设置为
<w:lvl w:ilvl="0" w:tplc="BBD6A362" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:start w:val="1" />
<w:numFmt w:val="decimal" />
<w:lvlText w:val="%1." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="720" w:hanging="360" />
</w:pPr>
<w:rPr>
<w:strike />
</w:rPr>
</w:lvl>
根据@Shelest 提供的解释,这里是使用 OpenXML SDK 的击打子弹的快速和肮脏的实现
public static void ReadAndStrikeBulletsWithOpenXml()
{
var sourcePath = @"C:\temp\test.docx";
var destinationPath = @"C:\temp\new-test.docx";
File.Copy(sourcePath, destinationPath);
using (var document = WordprocessingDocument.Open(destinationPath, true))
{
Numbering numbering = document.MainDocumentPart.NumberingDefinitionsPart.Numbering;
var abstractNum = numbering.ChildElements.FirstOrDefault(x => x.LocalName.Equals("abstractNum"));
if (abstractNum?.ChildElements != null)
{
foreach (var child in abstractNum.ChildElements)
{
if (child.OuterXml.Contains("<w:lvl"))
{
XmlDocument levelXml = new XmlDocument();
levelXml.LoadXml(child.OuterXml);
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(levelXml.NameTable);
namespaceManager.AddNamespace("w",
"http://schemas.openxmlformats.org/wordprocessingml/2006/main");
XmlNode runProperty = levelXml.SelectSingleNode("w:lvl/w:rPr", namespaceManager);
if (runProperty == null)
{
// Need to uncomment this if you prefer to strike all bullets at all levels
//child.InnerXml = child.InnerXml +
// "<w:rPr><w:strike w:val\"1\"/></w:rPr>";
}
else if (runProperty.InnerXml.Contains("w:strike"))
{
XmlDocument runXml = new XmlDocument();
runXml.LoadXml(runProperty.OuterXml);
XmlNamespaceManager runNamespaceManager = new XmlNamespaceManager(runXml.NameTable);
runNamespaceManager.AddNamespace("w",
"http://schemas.openxmlformats.org/wordprocessingml/2006/main");
XmlNode strikeNode = runXml.SelectSingleNode("w:rPr/w:strike", namespaceManager);
if (strikeNode?.Attributes != null)
{
if (strikeNode.Attributes["w:val"] == null)
{
// do nothing
}
else if (strikeNode.Attributes["w:val"].Value == "0")
{
child.InnerXml = child.InnerXml.Replace("w:strike w:val=\"0\"", "w:strike w:val=\"1\"");
}
}
}
}
}
}
document.MainDocumentPart.Document.Save();
document.Close();
}
}
我需要将样式应用于 MS Word
文档中的项目符号。
我可以使用 OpenXML
阅读完整的 docx
,然后使用 Run
节点
这就是我根据条件在其他区域应用样式的方式
private void StrikeAndUnderline(Run run)
{
if (run.RunProperties == null)
{
run.RunProperties = new RunProperties();
}
run.RunProperties.Strike = new Strike();
run.RunProperties.Strike.Val = true;
run.RunProperties.Underline = new Underline();
run.RunProperties.Underline.Val = UnderlineValues.Single;
}
但我没有得到 Run
属性 子弹
<w:p>
<w:pPr>
<w:pStyle w:val="ListParagraph"/>
<w:numPr>
<w:ilvl w:val="0"/>
<w:numId w:val="1"/>
</w:numPr>
</w:pPr>
<w:r>
<w:t>Paragraph one.</w:t>
</w:r>
</w:p>
不明显,但文档部分仅包含对存储在编号部分中的编号单元(具有所有格式和编号样式)的引用。
--文档部分。 所以在文档部分你必须grub NumberingLevelReference(w:ilvl) 和 NumberingId(w:numId).
--编号部分。 下一步是打开 Numbering 部分并搜索 NumberingInstance(w:num),其 NumberID 属性 与您在 Document 部分中看到的 NumberingId 相同。 现在,一旦您有了所需的 NumberingInstance,在它的子项中寻找 AbstractNumId 并记住它的值。 现在搜索具有您刚刚记住的相同 ID 的 AbstractNum 节点。
干杯!现在您拥有当前编号的属性。属性由编号级别分隔。所以现在搜索所需的 level(),即您在文档部分的编号属性中看到的那个。 一旦找到表示正确编号级别的节点,您应该将其设置为
<w:lvl w:ilvl="0" w:tplc="BBD6A362" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:start w:val="1" />
<w:numFmt w:val="decimal" />
<w:lvlText w:val="%1." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="720" w:hanging="360" />
</w:pPr>
<w:rPr>
<w:strike />
</w:rPr>
</w:lvl>
根据@Shelest 提供的解释,这里是使用 OpenXML SDK 的击打子弹的快速和肮脏的实现
public static void ReadAndStrikeBulletsWithOpenXml()
{
var sourcePath = @"C:\temp\test.docx";
var destinationPath = @"C:\temp\new-test.docx";
File.Copy(sourcePath, destinationPath);
using (var document = WordprocessingDocument.Open(destinationPath, true))
{
Numbering numbering = document.MainDocumentPart.NumberingDefinitionsPart.Numbering;
var abstractNum = numbering.ChildElements.FirstOrDefault(x => x.LocalName.Equals("abstractNum"));
if (abstractNum?.ChildElements != null)
{
foreach (var child in abstractNum.ChildElements)
{
if (child.OuterXml.Contains("<w:lvl"))
{
XmlDocument levelXml = new XmlDocument();
levelXml.LoadXml(child.OuterXml);
XmlNamespaceManager namespaceManager = new XmlNamespaceManager(levelXml.NameTable);
namespaceManager.AddNamespace("w",
"http://schemas.openxmlformats.org/wordprocessingml/2006/main");
XmlNode runProperty = levelXml.SelectSingleNode("w:lvl/w:rPr", namespaceManager);
if (runProperty == null)
{
// Need to uncomment this if you prefer to strike all bullets at all levels
//child.InnerXml = child.InnerXml +
// "<w:rPr><w:strike w:val\"1\"/></w:rPr>";
}
else if (runProperty.InnerXml.Contains("w:strike"))
{
XmlDocument runXml = new XmlDocument();
runXml.LoadXml(runProperty.OuterXml);
XmlNamespaceManager runNamespaceManager = new XmlNamespaceManager(runXml.NameTable);
runNamespaceManager.AddNamespace("w",
"http://schemas.openxmlformats.org/wordprocessingml/2006/main");
XmlNode strikeNode = runXml.SelectSingleNode("w:rPr/w:strike", namespaceManager);
if (strikeNode?.Attributes != null)
{
if (strikeNode.Attributes["w:val"] == null)
{
// do nothing
}
else if (strikeNode.Attributes["w:val"].Value == "0")
{
child.InnerXml = child.InnerXml.Replace("w:strike w:val=\"0\"", "w:strike w:val=\"1\"");
}
}
}
}
}
}
document.MainDocumentPart.Document.Save();
document.Close();
}
}