我有以下docx文件:
%LOOP = PolicyRelationship,NAME =生命,KEY =(PolicyNo = Policy.PolicyNo,关系= 'INSR')% %Life.EntityNo% - %Life.Name1 %% Life.Name2%
%ENDLOOP%
以下是带有标题行的表
封面类型Sum Insured Modal Premium BenefitVal SumValue ModalValue
这是该文件的最后一行。
我迭代地循环遍历LOOP块 - 用数据替换每个变量 所有剩余的文本都是从wordDoc剪切并粘贴到remainingParagraphs,然后在循环值粘贴回来之后重新粘贴到
由于条件
,并非所有段落都以这种方式处理if(wordDoc.Paragraphs [i] .ParentContainer == Container.Body)
条件。如果没有这个条件,所有段落都按正确的顺序处理,但XML已损坏。在这种情况下,表值不会被传输,因此在循环值之前显示不正确。
如果有一种更简单的方法,没有所有的切割和粘贴是理想的
这是我目前的代码段:
private void ProcessRepeatingText(DocX wordDoc, Dictionary<string, DocumentView> views)
{
var textDoc = wordDoc.Text;
var opn = 0;
while (opn != -1)
{
int cls, cma;
string tag, dto, rsn, key, where;
object repo;
//
// Get each loop DataView that has been defined, select a collection of data and store it in "views"
//
opn = textDoc.IndexOf("%LOOP=", StringComparison.OrdinalIgnoreCase);
if (opn == -1) break;
cls = textDoc.IndexOf("%", opn + 1, StringComparison.OrdinalIgnoreCase);
tag = textDoc.Substring(opn, cls - opn + 1);
cma = tag.IndexOf(",", StringComparison.OrdinalIgnoreCase);
dto = tag.Substring(6, cma - 6);
opn = tag.IndexOf("NAME=", cma, StringComparison.OrdinalIgnoreCase);
cls = tag.IndexOf(",", opn + 5, StringComparison.OrdinalIgnoreCase);
rsn = tag.Substring(opn + 5, cls - opn - 5);
cma = tag.IndexOf(",", cls, StringComparison.OrdinalIgnoreCase);
opn = tag.IndexOf("KEY=(", cma, StringComparison.OrdinalIgnoreCase);
cls = tag.IndexOf(")", opn + 4, StringComparison.OrdinalIgnoreCase);
key = tag.Substring(opn + 5, cls - opn - 5);
where = BuildWhereClause(dto, key, views);
repo = _baseRepository.CreateInstance(dto + "Repository");
var sec = repo.GetType().GetMethod("GetWhere").Invoke(repo, new object[] { where });
views.Add(rsn, new DocumentView { Rsn = rsn, Dto = dto, Data = sec, Pointer = 0 });
var loopTag = tag;
var i = -1;
var startAt = 0;
var tagBlocks = new List<TagBlock>();
opn = textDoc.IndexOf(loopTag, StringComparison.OrdinalIgnoreCase);
while (opn != -1)
{
if (textDoc.Substring(opn, 6) == "%LOOP=")
{
i++;
cls = textDoc.IndexOf("%", opn + 1, StringComparison.OrdinalIgnoreCase);
tagBlocks.Add(new TagBlock { From = opn, Upto = -1, FromIndex = -1, UptoIndex = -1 });
tagBlocks[i].FromIndex = IndexOfParagraph(wordDoc, textDoc.Substring(opn, cls - opn + 1), ref startAt);
opn = opn + 6;
}
if (textDoc.Substring(opn, 8) == "%ENDLOOP")
{
tagBlocks[i].Upto = opn;
if (tagBlocks[i].FromIndex != -1)
{
tagBlocks[i].UptoIndex = IndexOfParagraph(wordDoc, textDoc.Substring(opn, 9), ref startAt);
}
i--;
opn = opn + 8;
}
if (i == -1) break;
opn++;
}
var remainingParagraphs = new List<Novacode.Paragraph>();
for (i = tagBlocks[0].UptoIndex + 1; i < wordDoc.Paragraphs.Count; i++)
{
// if (wordDoc.Paragraphs[i].ParentContainer == ContainerType.Body)
// {
remainingParagraphs.Add(wordDoc.Paragraphs[i]);
wordDoc.RemoveParagraphAt(i);
i--;
// }
}
var loopDoc = DocX.Create(new MemoryStream());
if (tagBlocks[0].FromIndex != -1)
{
if (tagBlocks[0].UptoIndex != -1)
{
for (i = tagBlocks[0].FromIndex + 1; i < tagBlocks[0].UptoIndex; i++)
{
loopDoc.InsertParagraph(wordDoc.Paragraphs[i]);
}
for (i = tagBlocks[0].UptoIndex; i > tagBlocks[0].FromIndex; i--)
{
wordDoc.RemoveParagraphAt(i);
}
}
wordDoc.RemoveParagraphAt(tagBlocks[0].FromIndex);
}
else
{
opn = tagBlocks[0].From;
cls = textDoc.IndexOf("%", opn + 1, StringComparison.OrdinalIgnoreCase);
tag = textDoc.Substring(opn, cls - opn + 1);
var paragraph = wordDoc.Paragraphs.FirstOrDefault(x => x.Text.Contains(tag));
if (paragraph != null)
{
paragraph.ReplaceText(tag, "");
paragraph.ReplaceText("%ENDLOOP%", "");
}
}
var loopTxt = loopDoc.Text;
//
// Now get the secondary DataView data from "views"
//
DocumentView view;
if (views.TryGetValue(rsn, out view) != true)
{
return;
}
view.Pointer = 0;
var list = (IList)view.Data;
for (view.Pointer = 0; view.Pointer < list.Count; view.Pointer++)
{
var item = list[view.Pointer];
//
// Process conditional text, with a dependency on this secondary RSN, within this loop
//
loopTxt = ProcessConditionalText(loopDoc, view.Rsn, views, loopTxt);
//
// Process repeating text (LOOP..ENDLOOP) with a dependency on this secondary RSN
//
ProcessRepeatingText(loopDoc, views);
//
// Perform the data tag replacements, for this RSN, within this loop
//
ReplaceParameters(loopDoc, item, view.Rsn);
foreach (var p in loopDoc.Paragraphs)
{
wordDoc.InsertParagraph(p);
}
}
foreach (var p in remainingParagraphs)
{
wordDoc.InsertParagraph(p);
}
wordDoc.Paragraphs.FirstOrDefault(p => p.Text == loopTag)?.Remove(false);
wordDoc.ReplaceText(loopTag, "");
textDoc = wordDoc.Text;
views.Remove(rsn);
opn = 0;
}
}