MailMerge TaleStart-TableEnd:在多行行的页面末尾添加输入
MailMerge TaleStart-TableEnd: Add enter on end of page with multiline rows
我们有一个 MailMerge docx,其中包含以下 table:
_____________________________________________________________________________
Date Id Description Amount
_____________________________________________________________________________
{{TableStart {{Id}} {{Description}} € {{Amount
:Lines}}{{Da \# 0,00}}{{
te \@"dd-MM- TableEnd:Li
yyyy"}} nes}}
_____________________________________________________________________________
Total € {{Total \#
0,00}}
_____________________________________________________________________________
这是一个示例结果行:
____________________________________________________________________________
Date Id Description Amount
____________________________________________________________________________
03-09-2015 0001 Company Name € 25,00
Buyer Name 1, Buyer Name 2
Product description
Extra description line
如您所见,描述有多行。当到达页面末尾时,它只是继续下一页。因此,在上面的示例中,第 1 页末尾的行可能是这样的:
03-09-2015 0001 Company Name € 25,00
Buyer Name 1, Buyer Name 2
然后在第 2 页的开头这样:
Product description
Extra description line
我想要的是:当一个项目不再适合页面时,整个项目必须转到下一页的开头。基本上我想防止项目在页面之间拆分。有什么方法可以使用 MailMerge 完成此操作吗?
此外,我们在项目中使用 C#。这是我们用于 MailMerge 的代码。我认为询问 MailMerge 库中是否有允许我想要的行为的设置有点过于雄心勃勃。不管怎样,这是我们用来将数据和 docx 转换为 pdf 的代码:
var pdf = _documentService.CreateTableFile(new TableFileData(date, companyId,
dataList.Select(x => new TableRowData
{
Description = x.Description,
Amount = x.Amount,
Date = x.Date,
Id = x.Id
}).ToList()));
var path = Path.Combine(FileService.GetTemporaryPath(), Path.GetRandomFileName());
var file = Path.ChangeExtension(path, "pdf");
using (var fs = File.OpenWrite(file))
{
fs.Write(pdf, 0, pdf.Length);
}
Process.Start(file);
使用 CreateTableFile 方法:
public byte[] CreateTableFile(TableFileData data)
{
if (data == null) throw new ArgumentNullException("data");
const string fileName = "TableFile.docx";
var path = Path.Combine(_templatePath, fileName);
using (var fs = File.OpenRead(path))
{
var dataSource = new DocumentDataSource(data);
return GenerateDocument(fs, dataSource);
}
}
使用 GenerateDocument 方法:
private static byte[] GenerateDocument(Stream template, DocumentDataSource dataSource, IFieldMergingCallback fieldMergingCallback = null)
{
var doc = new Document(template);
doc.MailMerge.FieldMergingCallback = fieldMergingCallback;
doc.MailMerge.UseNonMergeFields = true;
doc.MailMerge.CleanupOptions = MailMergeCleanupOptions.RemoveContainingFields |
MailMergeCleanupOptions.RemoveUnusedFields |
MailMergeCleanupOptions.RemoveUnusedRegions |
MailMergeCleanupOptions.RemoveEmptyParagraphs;
doc.MailMerge.Execute(dataSource);
doc.MailMerge.ExecuteWithRegions((IMailMergeDataSourceRoot)dataSource);
doc.UpdateFields();
using (var ms = new MemoryStream())
{
var options = new PdfSaveOptions { WarningCallback = new AsposeWarningCallback() };
doc.Save(ms, options);
return ms.ToArray();
}
}
在@bibadia 在问题的第一条评论中提出建议后,我取消选中了 docx 中 table 设置的建议复选框:
成功了,非常感谢 bibadia!
我们有一个 MailMerge docx,其中包含以下 table:
_____________________________________________________________________________
Date Id Description Amount
_____________________________________________________________________________
{{TableStart {{Id}} {{Description}} € {{Amount
:Lines}}{{Da \# 0,00}}{{
te \@"dd-MM- TableEnd:Li
yyyy"}} nes}}
_____________________________________________________________________________
Total € {{Total \#
0,00}}
_____________________________________________________________________________
这是一个示例结果行:
____________________________________________________________________________
Date Id Description Amount
____________________________________________________________________________
03-09-2015 0001 Company Name € 25,00
Buyer Name 1, Buyer Name 2
Product description
Extra description line
如您所见,描述有多行。当到达页面末尾时,它只是继续下一页。因此,在上面的示例中,第 1 页末尾的行可能是这样的:
03-09-2015 0001 Company Name € 25,00
Buyer Name 1, Buyer Name 2
然后在第 2 页的开头这样:
Product description
Extra description line
我想要的是:当一个项目不再适合页面时,整个项目必须转到下一页的开头。基本上我想防止项目在页面之间拆分。有什么方法可以使用 MailMerge 完成此操作吗?
此外,我们在项目中使用 C#。这是我们用于 MailMerge 的代码。我认为询问 MailMerge 库中是否有允许我想要的行为的设置有点过于雄心勃勃。不管怎样,这是我们用来将数据和 docx 转换为 pdf 的代码:
var pdf = _documentService.CreateTableFile(new TableFileData(date, companyId,
dataList.Select(x => new TableRowData
{
Description = x.Description,
Amount = x.Amount,
Date = x.Date,
Id = x.Id
}).ToList()));
var path = Path.Combine(FileService.GetTemporaryPath(), Path.GetRandomFileName());
var file = Path.ChangeExtension(path, "pdf");
using (var fs = File.OpenWrite(file))
{
fs.Write(pdf, 0, pdf.Length);
}
Process.Start(file);
使用 CreateTableFile 方法:
public byte[] CreateTableFile(TableFileData data)
{
if (data == null) throw new ArgumentNullException("data");
const string fileName = "TableFile.docx";
var path = Path.Combine(_templatePath, fileName);
using (var fs = File.OpenRead(path))
{
var dataSource = new DocumentDataSource(data);
return GenerateDocument(fs, dataSource);
}
}
使用 GenerateDocument 方法:
private static byte[] GenerateDocument(Stream template, DocumentDataSource dataSource, IFieldMergingCallback fieldMergingCallback = null)
{
var doc = new Document(template);
doc.MailMerge.FieldMergingCallback = fieldMergingCallback;
doc.MailMerge.UseNonMergeFields = true;
doc.MailMerge.CleanupOptions = MailMergeCleanupOptions.RemoveContainingFields |
MailMergeCleanupOptions.RemoveUnusedFields |
MailMergeCleanupOptions.RemoveUnusedRegions |
MailMergeCleanupOptions.RemoveEmptyParagraphs;
doc.MailMerge.Execute(dataSource);
doc.MailMerge.ExecuteWithRegions((IMailMergeDataSourceRoot)dataSource);
doc.UpdateFields();
using (var ms = new MemoryStream())
{
var options = new PdfSaveOptions { WarningCallback = new AsposeWarningCallback() };
doc.Save(ms, options);
return ms.ToArray();
}
}
在@bibadia 在问题的第一条评论中提出建议后,我取消选中了 docx 中 table 设置的建议复选框:
成功了,非常感谢 bibadia!