我正在处理一个程序,该程序将图片插入到文档中指定位置的Microsoft Word文档中。例如,一个文本显示为" AUTOREPLACE 111"的页面,我会将其替换为以111开头的特定文件夹中的所有图像。
我可以使用Microsoft.Office.Interop.Word执行此操作,但此方法需要相对较长的时间来处理。添加了几百个图像,对于添加的每个图像,我必须添加裁剪值以及操纵图像对象中的其他几个变量。相对长的时间,我的意思是这需要至少一个小时来处理整个文档。
过去几天我一直在寻找更快的方法,并决定解压缩.docx文件,将图像添加到 media 文件夹,然后操纵必要的。用于将包含AUTOREPLACE文本的元素替换为图片元素的xml文档。
以下是包含AUTOREPLACE元素的xml:
<w:p w:rsidR="00411330" w:rsidRDefault="00411330" w:rsidP="005C6ED0">
<w:pPr>
<w:tabs>
<w:tab w:val="left" w:pos="720"/>
<w:tab w:val="left" w:pos="1260"/>
</w:tabs>
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
</w:rPr>
<w:br w:type="page"/>
</w:r>
<w:r>
<w:rPr>
<w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman"/>
</w:rPr>
<w:lastRenderedPageBreak/>
<w:t>AUTOREPLACE 111</w:t>
</w:r>
</w:p>
这是替换上面的xml
的w:p元素的xml<w:p w:rsidR="0080275B" w:rsidRDefault="0080275B" w:rsidP="0080275B">
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:rPr>
<w:noProof/>
</w:rPr>
<w:lastRenderedPageBreak/>
<w:drawing>
<wp:inline distT="0" distB="0" distL="0" distR="0">
<wp:extent cx="6031373" cy="8255000"/>
<wp:effectExtent l="0" t="0" r="7620" b="0"/>
<wp:docPr id="1" name="Picture 1"/>
<wp:cNvGraphicFramePr>
<a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/>
</wp:cNvGraphicFramePr>
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:nvPicPr>
<pic:cNvPr id="0" name=""/>
<pic:cNvPicPr/>
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed="rId17" r:link="rId18"/>
<a:srcRect l="7516" t="4798" r="4248" b="1768"/>
<a:stretch>
<a:fillRect/>
</a:stretch>
</pic:blipFill>
<pic:spPr>
<a:xfrm>
<a:off x="0" y="0"/>
<a:ext cx="6031373" cy="8255000"/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
</pic:spPr>
</pic:pic>
</a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing>
</w:r>
<w:r w:rsidR="00411330">
<w:br w:type="page"/>
</w:r>
</w:p>
我现在尝试设置的方法将遍历加载的XDocument的节点,直到它到达需要替换的节点,并将其替换为我创建的XElement对象。
我能够创建正确的w:p XElement,但是我在用我创建的元素替换原始元素时遇到了麻烦。
以下是从解压缩的Word文档中加载的document.xml的前3行:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 wp14">
<w:body>
替换后的 w:p 元素是 w:body
的子元素这是我到目前为止的测试代码:
XElement replaceElement = new XElement("replace");
ImagePageCreation iPage;
XDocument xdoc = XDocument.Load(xmlPath);
bool ReplaceFound = false;
XNamespace w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
foreach (XElement xe in xdoc.Descendants(w + "p"))
{
foreach (XElement xr in xe.Descendants(w + "r"))
{
foreach (XElement xt in xr.Descendants(w + "t"))
{
string innerText = xt.Value;
if (innerText.Length > 10)
{
if (!ReplaceFound)
{
if (innerText.Substring(0, 11) == "AUTOREPLACE")
{
//Console.WriteLine(innerText);
iPage = new ImagePageCreation("0080275B", "0080275B", "0080275B");
replaceElement = iPage.GetFullElement();
ReplaceFound = true;
break;
}
}
}
}
if (ReplaceFound)
{
break;
}
}
if (ReplaceFound)
{
xe = replaceElement;
}
}
我无法执行xe = replaceElement,因为xe是一个foreach迭代变量&#39;。
识别包含w:r元素的w:\ t元素的最佳方法是什么,该元素包含值为AUTOREPLACE 111的w:t元素并将其替换为我自己的w:p元素?
编辑:我知道我发布的代码示例只能在第一次替换时正常工作。我希望更换工作,然后我将纠正循环逻辑。
答案 0 :(得分:0)
您可以使用XNode.ReplaceWith()
方法将原始节点替换为替换,例如:
var query = from xe in xdoc.Descendants(w + "p")
let replacement = xe
.Descendants(w + "r").Descendants(w + "t")
.Where(xt => xt.Value.StartsWith("AUTOREPLACE"))
.Select(xt => new ImagePageCreation("0080275B", "0080275B", "0080275B").GetFullElement())
.FirstOrDefault()
where replacement != null
select new { Original = xe, Replacement = replacement };
foreach (var pair in query.ToList())
{
pair.Original.ReplaceWith(pair.Replacement);
}
如果您有多个替换,可以将.FirstOrDefault()
更改为.ToList()
:
XNamespace w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
var query = from xe in xdoc.Descendants(w + "p")
let replacement = xe
.Descendants(w + "r").Descendants(w + "t")
.Where(xt => xt.Value.StartsWith("AUTOREPLACE"))
.Select(xt => new ImagePageCreation("0080275B", "0080275B", "0080275B").GetFullElement())
.ToList()
where replacement.Count > 0
select new { Original = xe, ReplacementList = replacement };
foreach (var pair in query.ToList())
{
pair.Original.ReplaceWith(pair.ReplacementList);
}