一、为什么选择 iTextSharp.LGPLv2.Core 来实现PDF打印?
对于.net core的程序而言,如果部署环境是windows可能很多朋友会选择rdlc来生成PDF,通过rdlc来生成PDF格式相对较好控制,能覆盖到平时使用的大多数效果,最重要的还是免费,一旦希望部署到linux上 rdlc目前还无法很好支持PDF打印,对linux支持友好的方案大多数又需要收费,不收费的实现对于数据跨页支持又不友好(所谓的数据跨页,比如表格如果一页装不满,要分页显示的情况,如通过html生成PDF 、或者Excel生成PDF 、word 生成PDF等),经过不断的尝试目前发现 iTextSharp.LGPLv2.Core 是目前比较好的平替,下面来看看生成的效果。
图一:
图2:
以上简单了实现常用的一些效果,如页眉、页脚、页码、表格、合并单元格、表格插入条码、插入二维码、水印、插入文本段
二、演示
Nuget引入库
iTextSharp.LGPLv2.Core demo使用版本:3.4.11
新建控制台程序,演示关键代码如下:
//示例代码
//设置基础字体
var baseFont = BaseFont.CreateFont(@"simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//设置纸张 为A4横向
iTextSharp.text.Document doc = new iTextSharp.text.Document(PageSize.A4.Rotate(), 36, 36, 60, 60);
// Specify the file path where you want to save the PDF
string filePath = "table_example.pdf";
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(filePath, FileMode.Create));
// 添加页眉和页脚处理器
writer.PageEvent = new PDFReport();
// Open the document for writing
doc.Open();
#region 在固定坐标插入图片
string webRootPath = Directory.GetCurrentDirectory();
string relativePath = "QR_Code.png"; // 根据实际路径调整
string imagePath = Path.Combine(webRootPath, relativePath);
// 创建PdfContentByte对象,用于绘制内容
PdfContentByte contentByte = writer.DirectContent;
// 创建Image对象,表示要插入的图片
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(imagePath);
// 设置图片的位置(坐标),这里是将图片放在页面的坐标(100, 400)
img.SetAbsolutePosition(750, 450);
// 设置图片的大小,可以按需调整
img.ScaleAbsolute(80, 80);
// 将图片添加到PdfContentByte
contentByte.AddImage(img);
#endregion
#region 插入正文标题
// 创建一个标题段落
Paragraph title = new Paragraph("xxxxxx团股份有限公司", new iTextSharp.text.Font(baseFont, 16, iTextSharp.text.Font.BOLD));
title.Alignment = Element.ALIGN_CENTER; // 居中对齐
doc.Add(title);
Paragraph sub_title = new Paragraph("采购订单", new iTextSharp.text.Font(baseFont, 14));
sub_title.Alignment = Element.ALIGN_CENTER; // 居中对齐
sub_title.SpacingAfter = 5;
doc.Add(sub_title);
#endregion
#region 插入空白段落 模拟未来这块区域内容
//Paragraph contentParagraph1 = new Paragraph("A");
//doc.Add(contentParagraph1);
插入一个空白段落
//int blankParagraphHeight = 100; // 设置空白段落的高度(以点为单位)
//Paragraph blankParagraph = new Paragraph();
//blankParagraph.SpacingBefore = blankParagraphHeight; // 在段落前插入空白
//doc.Add(blankParagraph);
#endregion
#region 生成条形码
Barcode128 barcode = new Barcode128();
barcode.Code = "PNQWERUOI123ASD"; // 替换为你的条形码数据
barcode.StartStopText = false; // 禁止显示起始和结束字符
#endregion
#region 构造表格
PdfPTable table = new PdfPTable(3);
//默认好像是80%
//table.WidthPercentage = 100;
// 创建一个PdfPCell
PdfPCell pdfPCell_H01 = new PdfPCell(new Phrase("Column 1", new iTextSharp.text.Font(baseFont, 14)));
pdfPCell_H01.Rowspan = 2;
table.AddCell(pdfPCell_H01);
PdfPCell pdfPCell_H02 = new PdfPCell(new Phrase("Column 2", new iTextSharp.text.Font(baseFont, 14)));
pdfPCell_H02.Colspan = 2;
table.AddCell(pdfPCell_H02);
table.AddCell(new PdfPCell(new Phrase("Column 2.2 Column 2.2 Column 2.2 Column 2.2 Column 2.2 Column 2.2 Column 2.2 Column 2.2 ")));
table.AddCell(new PdfPCell(new Phrase("Column 2.33")));
// Add table data
for (int i = 1; i <= 30; i++)
{
table.AddCell(new PdfPCell(new Phrase("Row " + i + ", Cell 1")));
table.AddCell(new PdfPCell(new Phrase("Row " + i + ", Cell 2")));
//table.AddCell(new PdfPCell(new Phrase("Row " + i + ", Cell 3")));
// 将一维码嵌入到 PdfPCell 中
PdfPCell cell = new PdfPCell(barcode.CreateImageWithBarcode(writer.DirectContent, BaseColor.Black, BaseColor.Black));
//cell.Border = PdfPCell.NO_BORDER;
cell.HorizontalAlignment = Element.ALIGN_CENTER;
cell.VerticalAlignment = Element.ALIGN_CENTER;
// 添加 PdfPCell 到表格
table.AddCell(cell);
}
#region 中间穿插跨单元格
table.AddCell(new PdfPCell(new Phrase("测试中间插入图像", new iTextSharp.text.Font(baseFont, 14))));
PdfPCell pdfPCell_C01 = new PdfPCell(barcode.CreateImageWithBarcode(writer.DirectContent, BaseColor.Black, BaseColor.Black));
//cell.Border = PdfPCell.NO_BORDER;
pdfPCell_C01.HorizontalAlignment = Element.ALIGN_CENTER;
pdfPCell_C01.VerticalAlignment = Element.ALIGN_CENTER;
pdfPCell_C01.Colspan = 2;
table.AddCell(pdfPCell_C01);
#endregion
#region 汇总合并单元格
// 创建一个PdfPCell
PdfPCell pdfPCell = new PdfPCell(new Phrase("共计12元", new iTextSharp.text.Font(baseFont, 14)));
pdfPCell.Colspan = 3;
pdfPCell.VerticalAlignment = Element.ALIGN_CENTER;
pdfPCell.HorizontalAlignment = Element.ALIGN_RIGHT;
table.AddCell(pdfPCell);
#endregion
// Add the table to the document
doc.Add(table);
#endregion
#region 插入大量文本
doc.NewPage();
Paragraph text = new Paragraph(@"
1.交货期限:双方约定卖方在____年__月__日前交货,如若一方需要变更交货时间的,应当提前___日内以书面形式通知另一方,因此增加的费用,由提出方承担。
2.双方确认,交货地点为:___________(买方有权在卖方发货前变更交货地点,如因变更交货地点增加卖方费用的,由双方协商确认)。
", new iTextSharp.text.Font(baseFont, 12));
// 添加文本到文档
doc.Add(text);
#endregion
// Close the document
doc.Close();
生成页眉页脚相关类1:
public class PDFReport : PDFBase
{
#region GenerateHeader
/// <summary>
/// 生成页眉
/// </summary>
/// <param name="fontFilePath"></param>
/// <param name="pageNumber"></param>
/// <returns></returns>
public override PdfPTable GenerateHeader(iTextSharp.text.pdf.PdfWriter writer)
{
BaseFont baseFont = BaseFontForHeaderFooter;
iTextSharp.text.Font font_logo = new iTextSharp.text.Font(baseFont, 30, iTextSharp.text.Font.BOLD);
iTextSharp.text.Font font_header1 = new iTextSharp.text.Font(baseFont, 16, iTextSharp.text.Font.BOLD);
iTextSharp.text.Font font_header2 = new iTextSharp.text.Font(baseFont, 12, iTextSharp.text.Font.BOLD);
iTextSharp.text.Font font_headerContent = new iTextSharp.text.Font(baseFont, 12, iTextSharp.text.Font.NORMAL);
float[] widths = new float[] { 55, 300, 50, 90, 15, 20, 15 };
PdfPTable header = new PdfPTable(widths);
PdfPCell cell = new PdfPCell();
cell.BorderWidthBottom = 2;
cell.BorderWidthLeft = 0;
cell.BorderWidthTop = 0;
cell.BorderWidthRight = 0;
cell.FixedHeight = 35;
//cell.Phrase = new Phrase("LOGO", font_logo);
#region 添加图片
string webRootPath = Directory.GetCurrentDirectory();
string relativePath = "LOGO.png"; // 根据实际路径调整
string imagePath = Path.Combine(webRootPath, relativePath);
Image watermarkImage = Image.GetInstance(imagePath); // 替换为你的水印图片路径
cell.AddElement(watermarkImage);
#endregion
cell.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER;
cell.VerticalAlignment = iTextSharp.text.Element.ALIGN_CENTER;
cell.PaddingTop = -1;
header.AddCell(cell);
cell = GenerateOnlyBottomBorderCell(2, iTextSharp.text.Element.ALIGN_CENTER);
cell.Phrase = new Paragraph("PDF报表示例", font_header1);
header.AddCell(cell);
cell = GenerateOnlyBottomBorderCell(2, iTextSharp.text.Element.ALIGN_RIGHT);
cell.Phrase = new Paragraph("日期:", font_header2);
header.AddCell(cell);
cell = GenerateOnlyBottomBorderCell(2, iTextSharp.text.Element.ALIGN_LEFT);
cell.Phrase = new Paragraph(DateTime.Now.ToString("yyyy-MM-dd"), font_headerContent);
header.AddCell(cell);
cell = GenerateOnlyBottomBorderCell(2, iTextSharp.text.Element.ALIGN_RIGHT);
cell.Phrase = new Paragraph("第", font_header2);
header.AddCell(cell);
cell = GenerateOnlyBottomBorderCell(2, iTextSharp.text.Element.ALIGN_CENTER);
cell.Phrase = new Paragraph(writer.PageNumber.ToString(), font_headerContent);
header.AddCell(cell);
cell = GenerateOnlyBottomBorderCell(2, iTextSharp.text.Element.ALIGN_RIGHT);
cell.Phrase = new Paragraph("页", font_header2);
header.AddCell(cell);
return header;
}
#region GenerateOnlyBottomBorderCell
/// <summary>
/// 生成只有底边的cell
/// </summary>
/// <param name="bottomBorder"></param>
/// <param name="horizontalAlignment">水平对齐方式<see cref="iTextSharp.text.Element"/></param>
/// <returns></returns>
private PdfPCell GenerateOnlyBottomBorderCell(int bottomBorder,
int horizontalAlignment)
{
PdfPCell cell = GenerateOnlyBottomBorderCell(bottomBorder, horizontalAlignment, iTextSharp.text.Element.ALIGN_BOTTOM);
cell.PaddingBottom = 5;
return cell;
}
/// <summary>
/// 生成只有底边的cell
/// </summary>
/// <param name="bottomBorder"></param>
/// <param name="horizontalAlignment">水平对齐方式<see cref="iTextSharp.text.Element"/></param>
/// <param name="verticalAlignment">垂直对齐方式<see cref="iTextSharp.text.Element"/</param>
/// <returns></returns>
private PdfPCell GenerateOnlyBottomBorderCell(int bottomBorder,
int horizontalAlignment,
int verticalAlignment)
{
PdfPCell cell = GenerateOnlyBottomBorderCell(bottomBorder);
cell.HorizontalAlignment = horizontalAlignment;
cell.VerticalAlignment = verticalAlignment; ;
return cell;
}
/// <summary>
/// 生成只有底边的cell
/// </summary>
/// <param name="bottomBorder"></param>
/// <returns></returns>
private PdfPCell GenerateOnlyBottomBorderCell(int bottomBorder)
{
PdfPCell cell = new PdfPCell();
cell.BorderWidthBottom = 2;
cell.BorderWidthLeft = 0;
cell.BorderWidthTop = 0;
cell.BorderWidthRight = 0;
return cell;
}
#endregion
#endregion
#region GenerateFooter
public override PdfPTable GenerateFooter(iTextSharp.text.pdf.PdfWriter writer)
{
BaseFont baseFont = BaseFontForHeaderFooter;
iTextSharp.text.Font font = new iTextSharp.text.Font(baseFont, 10, iTextSharp.text.Font.NORMAL);
PdfPTable footer = new PdfPTable(3);
AddFooterCell(footer, "审阅:", font);
AddFooterCell(footer, "审批:", font);
AddFooterCell(footer, "制表:Ace", font);
return footer;
}
private void AddFooterCell(PdfPTable foot, String text, iTextSharp.text.Font font)
{
PdfPCell cell = new PdfPCell();
cell.BorderWidthTop = 2;
cell.BorderWidthRight = 0;
cell.BorderWidthBottom = 0;
cell.BorderWidthLeft = 0;
cell.Phrase = new Phrase(text, font);
cell.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER;
foot.AddCell(cell);
}
#endregion
}
生成页眉页脚相关类2:
public class PDFBase : PdfPageEventHelper
{
#region 属性
//private String _fontFilePathForHeaderFooter = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "SIMHEI.TTF");
private String _fontFilePathForHeaderFooter = @"simhei.ttf";
/// <summary>
/// 页眉/页脚所用的字体
/// </summary>
public String FontFilePathForHeaderFooter
{
get
{
return _fontFilePathForHeaderFooter;
}
set
{
_fontFilePathForHeaderFooter = value;
}
}
//private String _fontFilePathForBody = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "SIMSUN.TTC,1");
private String _fontFilePathForBody = @"simhei.ttf";
/// <summary>
/// 正文内容所用的字体
/// </summary>
public String FontFilePathForBody
{
get { return _fontFilePathForBody; }
set { _fontFilePathForBody = value; }
}
private PdfPTable? _header;
/// <summary>
/// 页眉
/// </summary>
public PdfPTable? Header
{
get { return _header; }
private set { _header = value; }
}
private PdfPTable? _footer;
/// <summary>
/// 页脚
/// </summary>
public PdfPTable? Footer
{
get { return _footer; }
private set { _footer = value; }
}
private BaseFont? _baseFontForHeaderFooter;
/// <summary>
/// 页眉页脚所用的字体
/// </summary>
public BaseFont? BaseFontForHeaderFooter
{
get { return _baseFontForHeaderFooter; }
set { _baseFontForHeaderFooter = value; }
}
private BaseFont? _baseFontForBody;
/// <summary>
/// 正文所用的字体
/// </summary>
public BaseFont? BaseFontForBody
{
get { return _baseFontForBody; }
set { _baseFontForBody = value; }
}
private Document? _document;
/// <summary>
/// PDF的Document
/// </summary>
public Document Document
{
get { return _document; }
private set { _document = value; }
}
#endregion
public override void OnOpenDocument(PdfWriter writer, Document document)
{
try
{
BaseFontForHeaderFooter = BaseFont.CreateFont(FontFilePathForHeaderFooter, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
BaseFontForBody = BaseFont.CreateFont(FontFilePathForBody, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
Document = document;
}
catch (Exception ex)
{
}
}
#region GenerateHeader
/// <summary>
/// 生成页眉
/// </summary>
/// <param name="writer"></param>
/// <returns></returns>
public virtual PdfPTable? GenerateHeader(iTextSharp.text.pdf.PdfWriter writer)
{
return null;
}
#endregion
#region GenerateFooter
/// <summary>
/// 生成页脚
/// </summary>
/// <param name="writer"></param>
/// <returns></returns>
public virtual PdfPTable? GenerateFooter(iTextSharp.text.pdf.PdfWriter writer)
{
return null;
}
#endregion
public override void OnEndPage(iTextSharp.text.pdf.PdfWriter writer, iTextSharp.text.Document document)
{
base.OnEndPage(writer, document);
//输出页眉
Header = GenerateHeader(writer);
Header.TotalWidth = document.PageSize.Width - 20f;
///调用PdfTable的WriteSelectedRows方法。该方法以第一个参数作为开始行写入。
///第二个参数-1表示没有结束行,并且包含所写的所有行。
///第三个参数和第四个参数是开始写入的坐标x和y.
Header.WriteSelectedRows(0, -1, 10, document.PageSize.Height - 20, writer.DirectContent);
//输出页脚
Footer = GenerateFooter(writer);
Footer.TotalWidth = document.PageSize.Width - 20f;
Footer.WriteSelectedRows(0, -1, 10, document.PageSize.GetBottom(50), writer.DirectContent);
}
}
总结
以上就是演示的内容,本文仅仅简单介绍了iTextSharp.LGPLv2.Core 的使用,而iTextSharp.LGPLv2.Core 提供了大量的方法用于渲染PDF,朋友们可以自行研究。