- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个在 IIS 7.5 上运行的 ASP.NET 4.5 Web 表单应用程序。
我正在尝试从其中一个我有自定义表单的页面生成一个 word 文档。
我上传了一个包含合并字段的 word 文档模板。在后面的代码中,我想根据 sql 数据库查询填充合并字段。
对于某些合并字段,我需要插入多行文本。其中一些甚至有项目符号列表。这些文本片段我无法存储在 sql 中,所以我将它们添加到带有书签的单独 word 文档中。
所以,简单回顾一下:
Template.dotx -> 包含合并字段
Data.docx -> 包含已用书签标记的文本片段。
我已设法使用 OpenXML 替换 Template.dotx 中的合并字段,但我找不到将书签中的数据放入合并字段的方法。
这对 Interop 非常有效,但是当我将它上传到服务器时遇到问题,所以我切换到 OpenXML。
这是我目前尝试过的:
private string GetBookmarkData(WordprocessingDocument secondWordDoc, string bookmarkKey)
{
string returnVal = "";
foreach (BookmarkStart bookmarkStart in secondWordDoc.MainDocumentPart.RootElement.Descendants<BookmarkStart>())
{
if(bookmarkStart.Name == bookmarkKey)
{
foreach(Run run in bookmarkStart.Parent.Descendants<Run>())
{
returnVal += run.Descendants<Text>().FirstOrDefault().Text + "<br/>";
}
}
}
return returnVal;
}
protected void PrintBtn_Click(object sender, EventArgs e)
{
string mainTemplate = Server.MapPath("~/MyFolder/Template.dotx");
string savePath = Server.MapPath("~/SaveFolder/Final.docx");
File.Copy(mainTemplate, savePath);
using(WordprocessingDocument firstDoc = WordprocessingDocument.Open(savePath, true))
{
using (WordprocessingDocument secondDoc = WordprocessingDocument.Open(Server.MapPath("~/MyFolder/Data.docx"), true))
{
foreach (FieldCode field in firstDoc.MainDocumentPart.RootElement.Descendants<FieldCode>())
{
var fieldNameStart = field.Text.LastIndexOf(" MERGEFIELD", System.StringComparison.Ordinal);
String fieldText = field.InnerText;
if (fieldText.StartsWith(" MERGEFIELD"))
{
Int32 endMerge = fieldText.IndexOf("\\");
Int32 fieldNameLength = fieldText.Length - endMerge;
String fieldName = fieldText.Substring(11, endMerge - 11);
fieldName = fieldName.Trim();
string autoFill = "";
switch (fieldName)
{
case "MergeField1":
autoFill = mergefield_1;
break;
case "MergeField2":
autoFill = mergefield_2;
break;
case "MergeField3":
autoFill = GetBookmarkData(secondDoc, "Bookmark1");
break;
case "MergeField4":
autoFill = GetBookmarkData(secondDoc, "Bookmark2");
break;
case "MergeField5":
autoFill = GetBookmarkData(secondDoc, "Bookmark3");
break;
}
}
foreach (Run run in firstDoc.MainDocumentPart.Document.Descendants<Run>())
{
foreach (Text txtFromRun in run.Descendants<Text>().Where(a => a.Text == "«" + fieldName + "»"))
{
txtFromRun.Text = autoFill;
}
}
}
}
}
firstDoc.ChangeDocumentType(WordprocessingDocumentType.Document);
firstDoc.MainDocumentPart.Document.Save();
}
}
那么这是做什么的呢?
当我点击一个按钮时,我调用方法 PrintBtn_Click。在做了一些 SQL 魔术(我没有包括在其中)之后,我初始化了一些变量,这些变量将填充每个合并字段。这个例子是一个简短的编辑版本。原来的要大得多。使用此代码,我设法填充了合并字段。它很好用。然而方法:`
string GetBookmarkData(WordprocessingDocument secondWordDoc, string bookmarkKey)`
并没有真正做到它应该做的。它应该进入 Data.docx,从我指定的书签中检索所有文本。它只返回没有项目符号或奇怪格式的行。
我在 Interop 上使用了相同的流程,没有遇到任何问题。我如何使用 OpenXML 执行此操作?带有项目符号的行是否存储在不同的 xml 中?
我试图检索 BookmarkStart 和 BookmarkEnd 之间的所有运行并从中获取文本。
secondDoc 实际上是 Data.docx,看起来像这样:
Bookmark1
• Text-Information 1 (This is just an example)
• Text-Information 2 (This is just an example)
• Text-Information 3 (This is just an example)
• Text-Information 4 (This is just an example)
Bookmark2
This is a list of multiple items:
Item 1 x.000,00
Item 2 x.000,00
Item 3 x.000,00
Item 4 x.000,00
Item 5 000,00
This is the conclusion for this list.
Following is a list of other multiple items:
Item 1 x.000,00
Item 2 x.000,00
Item 3 x.000,00
Item 4 x.000,00
Item 5 000,00
This is the conclusions for this list
Bookmark3
a) Another example of text that needs to go in the mergefield:
• Article 1 xxxx Quantity/Producer etc
• Article 2 xxxx Quantity/Producer etc
Some details about this block of text that is not relevant but I need to insert it in the merge field as well
因此,如果按下某个单选按钮,则“Bookmark1”/“Bookmark2”/“Bookmark3”之后的整个文本需要进入其特定的合并字段。我已将这些文本 block 添加为书签。正如我上面告诉你的,它只插入一些没有项目符号的行。例如,对应于 Bookmark2 的合并字段仅接收“这是一个包含多个项目的列表:”。
最佳答案
查看您的文档和代码,我发现有两个地方可能是您问题的根源:
首先:包含 Bookmark1
的 SecondTemplate.docx 的 xml 布局如下所示:
<Paragraph>
<Bookmarkstart name=bookmark1/>
<Run>
<Text "Item 1">
</Run>
</Paragraph>
<Paragraph>
<Run>
<Text "Item 2">
</Run>
</Paragraph>
<Paragraph>
<Run>
<Text "Item 3">
</Run>
</Paragraph>
<Paragraph>
<Run>
<Text "Item 4">
</Run>
<Bookmarkend/>
</Paragraph>
和你的代码:
if(bookmarkStart.Name == bookmarkKey)
{
foreach(Run run in bookmarkStart.Parent.Descendants<Run>())
{
returnVal += run.Descendants<Text>().FirstOrDefault().Text + "<br/>";
}
}
当 bookmarkstart.Parent
调用运行时,它匹配书签正上方的 Paragraph
:
<Paragraph>
<Bookmarkstart name=bookmark1/>
<Run>
<Text "Item 1">
</Run>
</Paragraph>
因此,当循环的其余部分执行时,您只会将“项目 1”拉入合并过程。您需要重新处理逻辑以正确匹配 BookmarkStart 和 BookmarkEnd 之间所有四个段落的运行中的文本。
第二:另一个经常让人们在 OpenXml 中犯错的问题是当您试图匹配 Descendants 调用中的 Run
时:
bookmarkStart.Parent.Descendants<Run>
如果您指的是 DocumentFormat.OpenXml.Drawing.Run
,而不是正确的“DocumentFormat.OpenXml.Wordprocessing.Run”,这会阻止匹配 - 所以将鼠标悬停在 上在 Visual Studio 中运行
并确保您匹配正确的运行。调整您的 using 语句以获得正确的语句。像
using Run = DocumentFormat.OpenXml.Wordprocessing.Run;
通常根据该文件中的其余代码使用。希望这些线索对您有所帮助。
关于c# - 通过OpenXML生成word文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46424062/
我有一个 .sln 文件,里面有几个项目。为了简单起见,让我们称它们为... 项目A 项目B 项目C ...其中 A 是引用 B 和 C 的主要项目。我的目标是更新我的构建脚本,为 ProjectA
我安装了 Magento,我想知道如何生成完整的 API 文档,例如 http://docs.magentocommerce.com/ 上的文档是使用 phpdoc 生成的。 Magento 中是否包
我通常使用jetbrains family ide。在为函数创建文档时非常有用,只需输入 /** 如何在创建文档时创建自定义标签,例如@date标签。 最佳答案 JavaScript、Java: st
我正在尝试使用 jOpenDocument library创建文档。我已经执行了创建电子表格的示例 - 代码编译并运行正常,但当我尝试使用 Excel Office 2012 或 Google Doc
如标题。 有没有介绍HTML DOM构造的图片? 最佳答案 DOM(文档 对象模型)从文档 节点开始。它被称为“根节点”。 观察下面的树(括号中对应的nodeType): [HTMLDocument]
我喜欢 ColdFusion Builder。但我不喜欢帮助只有 CF9 文档。有什么方法可以将其更改为拥有 ColdFusion 8 文档? 最佳答案 http://livedocs.adobe.c
这个问题在这里已经有了答案: What is the consequence of this bit of javascript? (4 个答案) 关闭 9 年前。 我看到一些 jQuery 脚本嵌
我有一个 XML 文件,其中包含需要在 Word 文档中填充的数据。 我需要找到一种方法来定义一个模板,该模板可用作从 XML 文件填充数据并创建输出文档的基线。 我相信有两种方法可以做到这一点。 创
我正在尝试查找有关如何使用 AVAudioEngine 的详细文档。有谁知道我在哪里可以找到它? 我找到了这个,但与文档丰富的 UI 内容相比,它似乎非常简陋。 https://developer.a
我对 Tensorflow 文档越来越感到恼火和沮丧。我在谷歌上搜索了有关 的文档 tf.reshape 我被定向到一个通用页面,例如 here 。我想查看 tf.reshape 的详细信息,而不是整
我正在学习本教程:http://moxleystratton.com/clojure/clojure-tutorial-for-the-non-lisp-programmer 然后遇到了这个片段: u
如何在 swagger 中为对象数组编写文档。这是我的代码,但我不知道如何访问对象数组中的数据。 { "first_name":"Sam", "last_name":"Smith",
是否有针对 Javascript 的 JavaDocs 之类的东西?当我在 netbeans IDE 中按 ctrl+space 时 写javascript,指定对象的javascript文档就出来了
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 5 年前。
我需要 JavaScript 中的 heredoc 之类的东西。你对此有什么想法吗?我需要跨浏览器功能。 我发现了这个: heredoc = '\ \ \ zzz\ \
WSDL 文档是包含一系列的,可描述某个 web service 的定义的,简单的 XML 文档 WSDL 文档结构 WSDL 文档用下表这些主要的元素来描述某个 web service 的
是否有 ocropus 的文档? 我正在寻找对以下功能的解释: make_SegmentPageByRAST(): segment() RegionExtractor(): setPageLines(
这个问题在这里已经有了答案: Understanding events and event handlers in C# (13 个回答) 4年前关闭。 我正在使用 NRECO 和 ffmpeg 对视
我正在尝试访问工作服务器以与名为 Spotfire 的应用程序一起使用。我的同事把这个传给我,现在已经休息了几个星期,我对他的建议有意见。 实际上,当我通过 localhost 运行我的 Web 应用
Elm 文档没有给出示例用法,因此很难理解类型规范的含义。在几个地方,我看到“a”用作参数标识符,例如 Platform.Cmd : map : (a -> msg) -> Cmd a -> Cmd
我是一名优秀的程序员,十分优秀!