对于我正在进行的项目,我正在调查我们团队通常不会用于生成文档的方法。通常情况下,我们使用ActiveReports生成我们为客户提供的PDF,但由于我们的纸张尺寸,这不是一个选项 - 我们一直有严重问题得到的东西不是8.5“x 11 “可以很好地使用浏览器端的PDF插件或我们支持的打印机。
我正在尝试做的具体事情是使用1 ... n 4“x6”索引卡创建一个文档。如上所述,我可以生成可变数量的数据条目。
我过去使用Open XML的唯一方法是采用模板,将关键字替换为我想要注入的数据,然后将生成的文档提供给客户端,如下所示:
报告类:
public class ThingReport : IDisposable
{
#region Variables / Properties
private readonly string _templatePath = string.Empty;
private MemoryStream _reportStream;
#endregion Variables / Properties
#region Constructor
public ThingReport(string templatePath)
{
_templatePath = templatePath;
}
#endregion Constructor
#region Methods
public void Dispose()
{
_reportStream.Dispose();
}
public void RunReport(IList<Thing> things)
{
_reportStream = new MemoryStream();
using (FileStream fs = File.OpenRead(_templatePath))
{
fs.CopyTo(_reportStream);
_reportStream.Seek(0x00000000, SeekOrigin.Begin);
fs.Close();
}
using (WordprocessingDocument pkgDoc = WordprocessingDocument.Open(_reportStream, true))
{
// Set basic properties of the document...
pkgDoc.PackageProperties.Creator = "My App";
pkgDoc.PackageProperties.Created = DateTime.Now;
pkgDoc.PackageProperties.Title = "Some document";
pkgDoc.PackageProperties.ContentType = "application/msword";
// Read the full document text, in prep for editing...
string docText;
using (StreamReader sr = new StreamReader(pkgDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
sr.Close();
}
// Replace the recipient.
// Source: https://msdn.microsoft.com/en-us/library/office/bb508261.aspx
Regex recipientRegex = new Regex("«Recipient»");
docText = recipientRegex.Replace(docText, things[0].PersonName);
// Template has 3 fields in it; replace those fields with details of child data.
for (int i = 0; i < 3; i++)
{
string presentedDate = string.Empty;
string presentedNotes = string.Empty;
if (i <= things.Count - 1)
{
var thing = things[i];
presentedDate = thing.thingDate.ToString("MM/dd/yyyy");
presentedNotes = thing.Notes;
}
string dateReplaceText = string.Format("«ThingDate{0}»", i + 1);
Regex dateRegex = new Regex(dateReplaceText);
docText = dateRegex.Replace(docText, presentedDate);
string noteReplaceText = string.Format("«ThingNote{0}»", i + 1);
Regex noteRegex = new Regex(noteReplaceText);
docText = noteRegex.Replace(docText, presentedNotes);
}
// Write the modified document to the stream.
using (StreamWriter sw = new StreamWriter(pkgDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
sw.Close();
}
// Close the unmanaged resource!
pkgDoc.Close();
}
}
public byte[] Export()
{
return _reportStream.ToArray();
}
#endregion Methods
}
我甚至从未试图同时在多个数据条目中使用Word模板。由于这是我的团队其他成员具有相同经验的技术,我不能问他们如何做到这一点,因为他们完全和我一样了解。
我确实查询了Open XML API for word documents,以及其他一些必要的谷歌搜索如何让Open XML API执行此操作......但我发现没有任何我能理解的内容。
问题:我能以何种方式使用可变数量的成员List<Thing>
,并使用Open XML获取MS Word模板以生成具有多个成员的文档页面数等于成员数,都使用完全相同的格式?
答案 0 :(得分:2)
我建议您创建一个包含多个合并字段的单词模板,以便与Thing /对象的成员进行映射,然后使用List执行Mail merge。
使用Syncfusion的DocIO库,您可以更轻松地实现它。 DocIO是一个.NET库,可以读取和写入Word 2003/2007/2010/2013/2016文件。如果您符合条件,则可以通过community license program免费获得整套控件(商业应用程序)。社区许可是完整的产品,没有任何限制或水印。
例如,让我们使用合并字段创建如下所示的Word文档模板,并考虑您有一个客户(列表)详细信息列表。
第1步:创建控制台应用程序
第2步:添加对Syncfusion.DocIO.Base,Syncfusion.Compression.Base和Syncfusion.OfficeChart.Base的引用
您也可以使用NuGet将这些引用添加到您的项目中
第3步:复制&amp;粘贴以下代码段。确保正确引用输入字模板。
此代码将根据您的要求生成文档,对于每个/客户,它将在生成的Word文档中生成单独的页面。
using System.Collections.Generic;
using Syncfusion.DocIO.DLS;
using Syncfusion.DocIO;
namespace DocIO_MailMerge
{
class Program
{
static void Main(string[] args)
{
List<Customer> customers = new List<Customer>();
customers.Add(new Customer("Maria", "Anders", "maria.Anders@example.com", "USA"));
customers.Add(new Customer("Ana", "Trujillo", "ana.trujillp@example.com", "USA"));
customers.Add(new Customer("Antonio", "Moreno", "antonio.moreno@example.com", "UK"));
customers.Add(new Customer("Thomas", "Hardy", "thomas.hardy@example.com", "Mexico"));
using (WordDocument wordDocument = new WordDocument(@"Template.docx"))
{
wordDocument.MailMerge.Execute(customers);
wordDocument.Save("Result.docx", FormatType.Docx);
}
System.Diagnostics.Process.Start("Result.docx");
}
}
class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string MailID { get; set; }
public string Country { get; set; }
public Customer(string firstName, string lastName, string emailID, string country)
{
FirstName = firstName;
LastName = lastName;
MailID = emailID;
Country = country;
}
}
}
注意:我为Syncfusion工作。