【发布时间】:2018-09-27 17:36:52
【问题描述】:
我正在开发一个用于在 PDF 文件中生成发票的 Windows 窗体应用程序。
此 Winform 应用程序正在使用 PDF 模板来创建 PDF 文件。
这是 PDF 模板的屏幕截图(此模板是使用 Adobe Acrobat XI Lite Portable 创建的):
我在此代码中使用itextsharp(版本 5.5.13) 来生成 PDF 文件:
private void GenerateInvoice(DataTable tbl_template_variables, DataTable tbl_details_invoice)
{
using (PdfReader pdfReader = new PdfReader(plantilla__Invoice__manual))
{
try
{
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(location_output_file, FileMode.Create));
AcroFields pdfFormFields = pdfStamper.AcroFields;
// Loop DataTable and set the value in the specified field.
for (int i = 0; i < tbl_template_variables.Rows.Count; i++)
{
pdfFormFields.SetField(tbl_template_variables.Rows[i][0].ToString(), tbl_template_variables.Rows[i][1].ToString(), true);// set form pdfFormFields
}
#region Details's table Invoice
PdfPCell cell = null;
PdfPTable table = null;
table = new PdfPTable(9);
table.HorizontalAlignment = Element.ALIGN_LEFT;
table.SetWidths(new float[] { 22f, 22f, 22f, 22f, 22f, 22f, 22f, 22f, 22f });
//table.SpacingBefore = 5;
table.TotalWidth = 800f;
for (int i = 0; i < tbl_details_invoice.Rows.Count; i++)
{
DataRow row = tbl_details_invoice.Rows[i];
object Invoice_PDFColumn0_value = row.Field<string>("PROVIDER") == null ? string.Empty : row.Field<string>("PROVIDER").ToString();
object Invoice_PDFColumn1_value = row.Field<string>("DESCRIPTION") == null ? string.Empty : row.Field<string>("DESCRIPTION").ToString();
object Invoice_PDFColumn2_value = row.Field<string>("PPTO") == null ? string.Empty : row.Field<string>("PPTO").ToString();
object Invoice_PDFColumn3_value = row.Field<string>("JOB_MEDIA_TYPE") == null ? string.Empty : row.Field<string>("JOB_MEDIA_TYPE").ToString();
object Invoice_PDFColumn4_value = row.Field<string>("VEND_INV_NO") == null ? string.Empty : row.Field<string>("VEND_INV_NO").ToString();
//object Invoice_PDFColumn5_value = row.Field<string>("ORDER_MEDIA") == null ? string.Empty : row.Field<string>("ORDER_MEDIA").ToString();
//object Invoice_PDFColumn6_value = row.Field<string>("ACTIVITY_MONTH") == null ? string.Empty : row.Field<string>("ACTIVITY_MONTH").ToString();
object Invoice_PDFColumn7_value = row.Field<string>("COMMISSIONABLE") == null ? string.Empty : row.Field<string>("COMMISSIONABLE").ToString();
object Invoice_PDFColumn8_value = row.Field<string>("NON_COMMISSIONABLE") == null ? string.Empty : row.Field<string>("NON_COMMISSIONABLE").ToString();
string Invoice_PDFColumn9_value = row.Field<string>("IVA_PROVEEDOR") == null ? string.Empty : row.Field<string>("IVA_PROVEEDOR").ToString();
string Invoice_PDFColumn10_value = row.Field<string>("TOTAL") == null ? string.Empty : row.Field<string>("TOTAL").ToString();
//Columns table
cell = PhraseCell(new Phrase(Invoice_PDFColumn0.ToString(), GettypeStyle()));
table.AddCell(cell);
cell = PhraseCell(new Phrase(Invoice_PDFColumn1.ToString(), GettypeStyle()));
table.AddCell(cell);
cell = PhraseCell(new Phrase(Invoice_PDFColumn2.ToString(), GettypeStyle()));
table.AddCell(cell);
cell = PhraseCell(new Phrase(Invoice_PDFColumn3.ToString(), GettypeStyle()));
table.AddCell(cell);
cell = PhraseCell(new Phrase(Invoice_PDFColumn4.ToString(), GettypeStyle()));
table.AddCell(cell);
//cell = PhraseCell(new Phrase(Invoice_PDFColumn5.ToString(), GettypeStyle()));
//table.AddCell(cell);
//cell = PhraseCell(new Phrase(Invoice_PDFColumn6.ToString(), GettypeStyle()));
//table.AddCell(cell);
cell = PhraseCell(new Phrase(Invoice_PDFColumn7.ToString(), GettypeStyle()));
table.AddCell(cell);
cell = PhraseCell(new Phrase(Invoice_PDFColumn8.ToString(), GettypeStyle()));
table.AddCell(cell);
cell = PhraseCell(new Phrase(Invoice_PDFColumn9.ToString(), GettypeStyle()));
table.AddCell(cell);
cell = PhraseCell(new Phrase(Invoice_PDFColumn10.ToString(), GettypeStyle()));
table.AddCell(cell);
}
ColumnText ct = new ColumnText(pdfStamper.GetOverContent(1));
ct.AddElement(table);
//iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(18, 370, 800, 36);
iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(16, 320, 900, 16);
rect.Border = iTextSharp.text.Rectangle.LEFT_BORDER | iTextSharp.text.Rectangle.RIGHT_BORDER;
rect.BorderWidth = 15;
rect.BorderColor = new BaseColor(0, 0, 0);
rect.Border = iTextSharp.text.Rectangle.BOX;
ct.SetSimpleColumn(rect);
ct.Go();
#endregion
// flatten the form to remove editting options, set it to false
// to leave the form open to subsequent manual edits
pdfStamper.FormFlattening = true;
pdfStamper.FreeTextFlattening = true;
pdfStamper.Writer.CloseStream = true;
pdfStamper.Close();// close the pdf
}
catch (Exception ex)
{
// No errors (yet).
}
}
}
这是结果(仅包含一些细节):
这段代码我面临的问题是,如果详细信息表有更多行,则这些行会在生成的页面中被覆盖(并且不会生成更多页面)。
这是覆盖数据的结果:
我正在寻找使用此 PDF 模板正确生成 PDF 发票的方法(如果可能)。
这是迄今为止我尝试后得到的最接近的有利结果:
- 修改 PDF 模板以在 detail headers 下添加变量并更新字段的值以添加换行符,但是,似乎 PDF 中变量的大小很重要,因此,换行符不会扩展变量 (并强制) 以生成更多页面。
- 使用HTMLWorker(已弃用) 强制使用 HTML 模板(类似于 PDF 模板的结构)。此方法适用于在打印 Details 表的行时生成多个页面,但未应用 CSS。
- 使用 PdfDocument、PdfParagraph 和类似类的组合(尝试遵循我找到的指南 here),但老实说,我不知道如何在特定坐标中设置并使用正确的度量为生成的 PDF 文件中的每个元素设置点。
-
Download iText7 用于使用
HtmlConverter.ConvertToPdf功能,但在这种情况下,我在生成旋转的 PDF 时遇到问题。文档在 java 我不熟悉。 - 我在 Oracle 中为 Create a PDF Template 找到了此文档 - 专注于“定义重复字段组”部分,但如果可以在 C# 中使用,我也找不到如何编辑 PDF 模板的源代码WinForms 应用程序。
所有提到的尝试给我带来的问题多于解决方案,因此,我想多花点时间使用 PDF 模板方法。
我整整一周都在做这个任务,但我没有想法。
我将编辑我的问题以添加与我面临的相同问题的相关问题:
我几乎不想避免创建 给我代码 问题,但是,欢迎任何关于如何正确生成 PDF 文件的建议或想法。
【问题讨论】:
标签: itextsharp c# winforms pdf itext