c# openxml:复制带有字体和对齐方式的段落
c# openxml : copy paragraph with font and alignment
我想将word *.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));
}
}
但原始格式丢失了 - 我的意思是字体和对齐方式都已更改。这里的解决方案是什么?
首先,使用 item.InnerXml
而不是 item.InnerText
,并将新段落 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 guide 修改而来的。它将 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
实现类似的方法。
我想将word *.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));
}
}
但原始格式丢失了 - 我的意思是字体和对齐方式都已更改。这里的解决方案是什么?
首先,使用 item.InnerXml
而不是 item.InnerText
,并将新段落 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 guide 修改而来的。它将 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
实现类似的方法。