C#/Java 动态生成电子发票
电子发票是电商时代的产物,PDF发票是最常见的电子发票之一。在这篇文章中,我将给大家分享一个免费的动态生成PDF电子发票的C#方案,并在文章末尾附上Java解决方案。 典型的发票包含客户和供应商的名称和地址、发票编号、购买物品的描述、付款金额等信息。为了动态地生成发票,我使用MS Word创建了一个模板,在该模板中设计好想要呈现的大部分内容及文档样式,然后通过代码替换文本和插入新内容,最后保存为PDF文档。用代码操作Word文档的部分需要使用免费版的Spire.Doc for .NET7.1。 创建模板 为了能自动计算总金额,需要在某些单元格添加公式域。例如,单元格E2包含公式“=C2*D2”,该公式将计算单元格B2中商品的总价。当买家购买超过一件商品时,我们需要在表格添加更多行并动态更新一些单元格的公式。 图1?发票模板 如何替换文本 doc.Replace("#orderNum",2516595027true,1)">true); 如何更新表格二现在,让我们看看如何向现有表格添加行,如何将数据填充至表格,以及如何动态地更新公式。为了使逻辑更清晰,我创建了三个方法,并制作了图2,来展示它们的具体含义以及它们之间的调用关系。 图2 自定义方法的含义及调用关系 下面,看一下这三个方法的代码片段: 1. AddRows() 此方法实际上复制了现有表格的第二行,将复制行依次添加到第二行的下面。新行继承了第二行的单元格格式、字体样式和公式。因此,我们需要依次更新新行中的公式,以及下面随行数增加而变化的公式。 private static void AddRows(Table table,1)">int rowNum) { for (int i = 0; i < rowNum; i++) { //将指定个数的第二行的复制行依次添加到第二行下面 table.Rows.Insert(2 + i,table.Rows[1].Clone()); 更新“金额”所对应单元格的公式 foreach (var item in table.Rows[2 + i].Cells[4].Paragraphs[0].ChildObjects) { if (item is Field) { Field field = item as Field; field.Code = string.Format(=C{0}*D{0}# "0.00"3 + i); } break; } } 更新“折扣金额”对应的单元格的公式 4 + rowNum].Cells[].ChildObjects) { Field) { Field field = item Field; field.Code = =E{0}*0.05# "0.00" rowNum); } ; } 更新“总计”对应的单元格的公式 5 + rowNum].Cells[=E{0}-E{1}# "¥#,##0.00"3 + rowNum,1)">5 +; } } ? ?2. FillTableWithData() 此方法仅用于将sting[][]类型数据从表格的第二行开始写入表格。 void FillTableWithData(Table table,1)">string[][] data) { int r = 0; r < data.Length; r++) { int c = 0; c < data[r].Length; c++) { 将数据从表格的第二行开始写入表格 table.Rows[r + 1].Cells[c].Paragraphs[0].Text = data[r][c]; } } } ? 3. WriteDataToDocument() 由于发票模板已经有一行(第二行)用于显示一项商品,因此我们需要判断是否需要添加更多行。如果客户只购买一项商品,模板文档就可以容纳商品信息并输出结果;否则,我们需要添加行来容纳更多的项目,并动态更新公式以获得正确的总金额。 void WriteDataToDocument(Document doc,1)">[][] purhcaseData) { 获取Word模板中的第二个表格 Table table = doc.Sections[0].Tables[1] Table; 若购买商品多于一项,则添加purhcaseData.Length - 1个行 if (purhcaseData.Length > ) { AddRows(table,purhcaseData.Length - ); } 将购买数据填充至表格 FillTableWithData(table,purhcaseData); } WriteDataToDocument()方法的参数之一是sting[][]对象,该对象存储了客户的购买信息,它的每个元素都是一个字符串数组,可以这样设置: string[] product = new string[] { 1023华为 P30 Pro (8G+128G)全网通14288" }; string[][]的长度则是商品的项数,如果长度大于1,则需要添加[长度 - 1]个新行。 生成发票以下是Main函数中用于生成PDF发票的代码。 using Spire.Doc; Spire.Doc.Fields; namespace CreatePdfInvoice { class Program { void Main([] args) { 加载Word模板文档 Document doc = new Document(); doc.LoadFromFile(Invoice-Template.docx"); 替换文档中以#开头的文本 doc.Replace(#customerName小伟true); doc.Replace(#contactNum13601234567#shippingAdd北京市海淀区幸福小区1幢2单元3号#orderDate2019-05-30定义客户购买数据 string[][] purchaseData = { string[]{},1429华为Watch GT运动版212881268华为无线耳机 FreeBuds 2Pro7991281华为 MateBook 14 (i5 8G 512G)5999将购买数据写入模板文档的第二个表格 WriteDataToDocument(doc,purchaseData); 更新域 doc.IsUpdateFields = ; 保存为PDF格式文档 doc.SaveToFile(Invoice.pdf,FileFormat.PDF); System.Diagnostics.Process.Start(); } } } 生成的结果文档如下: 图 3 多项目PDF发票 ? 如果你输入购买数据只有一行,那么你将得到如图4所示的结果文档。 string[][] purchaseData = {"},}; 图4 单项目PDF发票 ? 工程下载
? ? ? 注: 免费版?Spire.Doc能加载和生成的Word文档不能超过500个段落或25个表格,将Word文档保存为PDF时仅支持前3页。绝大多数发票只有1页或2页,所以该方案适用于大多数情况。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |