c#用iTextSharp生成pdf文档
在应用中有时需要生成pdf文档。在vs中用nuget添加 iTextSharp的引用,就可以方便的操作pdf了
先上一段常用操作的代码
using iTextSharp.text.pdf;
using System.IO;
using iTextSharp.text;
namespace Net.BLL.Pdf
{
/// <summary>
/// PDF文档操作类
/// </summary>
//------------------调用--------------------------
//PDFOperation pdf = new PDFOperation();
//pdf.Open(filepath); 或 pdf.Open(new FileStream(pdfNewFile, FileMode.Create));
//pdf.SetBaseFont(@"C:\Windows\Fonts\SIMHEI.TTF");
//pdf.AddParagraph("测试文档(生成时间:" + DateTime.Now + ")", 15, 1, 20, 0, 0);
//pdf.Close();
//-------------------------------
public class PDFOperation
{
#region 构造函数
/// <summary>
/// 构造函数,默认A4大小
/// </summary>
public PDFOperation()
{
rect = PageSize.A4;
document = new Document(rect);
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="type">页面大小(如"A4")可选值A1-A10,B1,B2等 参考PageSize的值</param>
public PDFOperation(string type)
{
SetPageSize(type);
document = new Document(rect);
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="type">页面大小(如"A4") 可选值A1-A10,B1,B2等 参考PageSize的值</param>
/// <param name="marginLeft">内容距左边框距离</param>
/// <param name="marginRight">内容距右边框距离</param>
/// <param name="marginTop">内容距上边框距离</param>
/// <param name="marginBottom">内容距下边框距离</param>
public PDFOperation(string type, float marginLeft, float marginRight, float marginTop, float marginBottom)
{
SetPageSize(type);
document = new Document(rect, marginLeft, marginRight, marginTop, marginBottom);
}
#endregion
#region 私有字段
private Font font;
private Rectangle rect; //文档大小
private Document document;//文档对象
private BaseFont basefont;//字体
private PdfWriter pdfWriter;
#endregion
#region 设置字体
/// <summary>
/// 设置字体 D:\\Windows\\Fonts\\SIMSUN.TTC 如该字体,没有可以从网上下载后放在系统字体文件夹下
/// 不设置的话默认字体不支持中文
/// </summary>
public void SetBaseFont(string path)
{
basefont = BaseFont.CreateFont(path, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
}
/// <summary>
/// 设置字体
/// </summary>
/// <param name="size">字体大小</param>
public void SetFont(float size)
{
font = new Font(basefont, size);
}
#endregion
#region 设置页面大小
/// <summary>
/// 设置页面大小
/// </summary>
/// <param name="type">页面大小(如"A4") 可选值A1-A10,B1,B2等 参考PageSize的值</param>
public void SetPageSize(string type)
{
switch (type.Trim())
{
case "A4":
rect = PageSize.A4;
break;
case "A8":
rect = PageSize.A8;
break;
}
}
#endregion
#region 实例化文档
/// <summary>
/// 实例化文档
/// </summary>
/// <param name="os">文档相关信息(如路径,打开方式等)</param>
public void GetInstance(Stream os)
{
pdfWriter = PdfWriter.GetInstance(document, os);
}
#endregion
#region 打开文档对象
/// <summary>
/// 打开文档对象
/// </summary>
/// <param name="os">文档相关信息(如路径,打开方式等)</param>
public void Open(Stream os)
{
GetInstance(os);
document.Open();
}
/// <summary>
/// 打开文档对象
/// </summary>
/// <param name="pdfNewFile">文档路径</param>
public void Open(string pdfNewFile)
{
pdfWriter = PdfWriter.GetInstance(document, new FileStream(pdfNewFile, FileMode.Create));
document.Open();
}
#endregion
#region 关闭打开的文档
/// <summary>
/// 关闭打开的文档
/// </summary>
public void Close()
{
document.Close();
pdfWriter.Close();
}
#endregion
#region 添加段落
/// <summary>
/// 添加段落
/// </summary>
/// <param name="contents">内容</param>
/// <param name="fontsize">字体大小</param>
public void AddParagraph(string contents, float fontsize)
{
SetFont(fontsize);
Paragraph pra = new Paragraph(contents, font);
document.Add(pra);
}
/// <summary>
/// 添加段落,文本段
/// </summary>
/// <param name="contents">内容</param>
/// <param name="fontsize">字体大小</param>
/// <param name="Alignment">对齐方式(1为居中,0为居左,2为居右)</param>
/// <param name="SpacingAfter">段后空行数(0为默认值)</param>
/// <param name="SpacingBefore">段前空行数(0为默认值)</param>
/// <param name="MultipliedLeading">行间距(0为默认值)</param>
public void AddParagraph(string contents, float fontsize, int Alignment, float SpacingAfter, float SpacingBefore, float MultipliedLeading)
{
SetFont(fontsize);
Paragraph pra = new Paragraph(contents, font);
pra.Alignment = Alignment;
if (SpacingAfter != 0)
{
pra.SpacingAfter = SpacingAfter;
}
if (SpacingBefore != 0)
{
pra.SpacingBefore = SpacingBefore;
}
if (MultipliedLeading != 0)
{
pra.MultipliedLeading = MultipliedLeading;
}
document.Add(pra);
}
#endregion
#region 添加图片
/// <summary>
/// 添加图片
/// </summary>
/// <param name="path">图片路径</param>
/// <param name="Alignment">对齐方式(1为居中,0为居左,2为居右)</param>
/// <param name="newWidth">图片宽(0为默认值,如果宽度大于页宽将按比率缩放)</param>
/// <param name="newHeight">图片高</param>
public void AddImage(string path, int Alignment, float newWidth, float newHeight)
{
Image img = Image.GetInstance(path);
img.Alignment = Alignment;
if (newWidth != 0)
{
img.ScaleAbsolute(newWidth, newHeight);
}
else
{
if (img.Width > PageSize.A4.Width)
{
img.ScaleAbsolute(rect.Width, img.Width * img.Height / rect.Height);
}
}
document.Add(img);
}
#endregion
#region 添加链接、点
/// <summary>
/// 添加链接
/// </summary>
/// <param name="Content">链接文字</param>
/// <param name="FontSize">字体大小</param>
/// <param name="Reference">链接地址</param>
public void AddAnchorReference(string Content, float FontSize, string Reference)
{
SetFont(FontSize);
Anchor auc = new Anchor(Content, font);
auc.Reference = Reference;
document.Add(auc);
}
/// <summary>
/// 添加链接点
/// </summary>
/// <param name="Content">链接文字</param>
/// <param name="FontSize">字体大小</param>
/// <param name="Name">链接点名</param>
public void AddAnchorName(string Content, float FontSize, string Name)
{
SetFont(FontSize);
Anchor auc = new Anchor(Content, font);
auc.Name = Name;
document.Add(auc);
}
#endregion
#region === 其它属性设置 ===
/// <summary>
/// 设置title
/// </summary>
/// <param name="title"></param>
public void SetTitle(string title)
{
document.AddTitle(title);
}
/// <summary>
/// 设置subject
/// </summary>
/// <param name="subject"></param>
public void SetSubject(string subject)
{
document.AddSubject(subject);
}
/// <summary>
/// 设置keywords
/// </summary>
/// <param name="keywords"></param>
public void SetKeywords(string keywords)
{
document.AddKeywords(keywords);
}
/// <summary>
/// 设置creator
/// </summary>
/// <param name="creator"></param>
public void SetCreator(string creator)
{
document.AddCreator(creator);
}
/// <summary>
/// 设置author
/// </summary>
/// <param name="author"></param>
public void SetAuthor(string author)
{
document.AddAuthor(author);
}
#endregion
}
}
如何调用代码中详细的说明,但是你会发现,操作pdf文档过程中添加文本,添加图片这些常见的方法都没有问题,但最终生成出来的文档却差强人意
原因在哪?当然是排版的问题,要调整好文本段落与图片的布局,位置很是麻烦。虽然iTextSharp支持图片,文本的插入位置设置,但用代码来设置还是很费劲。
最好的方式就是先做好pdf文档的模板,利用模板来生成想要的pdf文档,这样省时省力,但前提就是模板文件要准备好。
模板文件可以利用pdf编辑器生成,你可以考虑用Adobe Acrobat DC系列的工具来做,做文档的过程中最重要的就是在文档中添加好对应的表单,在代码中分别在对应的表单域名中添加对应的元素。这样的话,位置,样式统统可以在模板文档中设置中,代码中只管添加元素进去。
下面是利用模板来生成pdf文档的代码
using System;
using System.Collections.Generic;
using iTextSharp.text.pdf;
using System.IO;
using iTextSharp.text;
namespace Net.BLL.Pdf
{
/// <summary>
/// 使用pdf模板方式创建pdf的帮助类
/// </summary>
//------- 调用示例 --------
// Net.BLL.Pdf.PdfWithTemplateHelper pdf = new Net.BLL.Pdf.PdfWithTemplateHelper();
// pdf.Open("E:\\PdfTest\\mytemplate.pdf", "E:\\PdfTest\\test.pdf");
// pdf.PutText("txttitle", "pdf生成测试");
// pdf.PutText("txtuser001", "Me \r\n生日:1988-8-9 \r\n爱好:运动、健身、旅游");
// pdf.PutImage(1, "img001", "e:/PdfTest/pic01.jpg");
// pdf.PutText("txtuser002", "肖鼠:鼠年出生的人的本命佛是千手观音,得千手观音庇佑。肖鼠的人财运好,在十二生肖中属于富贵型!");
// pdf.PutImage(1, "img002", "e:/PdfTest/pic02.jpg");
// pdf.PutText("txtbuddha001", "生命在于运动!人生不止,运动不息!");
// pdf.Close();
//--------- end -----------
public class PdfWithTemplateHelper
{
PdfReader pdfReader = null;
PdfStamper pdfStamper = null;
AcroFields pdfFormFields = null;
PdfWriter pdfWriter = null;
public PdfWithTemplateHelper()
{
}
/// <summary>
/// 创建文档
/// </summary>
/// <param name="pdfTemplateFile">模板文件路径</param>
/// <param name="pdfNewFile">要生成的文档路径</param>
public void Open(string pdfTemplateFile, string pdfNewFile)
{
pdfReader = new PdfReader(pdfTemplateFile);
pdfStamper = new PdfStamper(pdfReader, new FileStream(pdfNewFile, FileMode.OpenOrCreate));
pdfFormFields = pdfStamper.AcroFields;
pdfStamper.FormFlattening = true;
}
/// <summary>
/// 关闭并保存文档
/// </summary>
public void Close()
{
pdfStamper.Close();
pdfReader.Close();
pdfStamper = null;
pdfReader = null;
pdfFormFields = null;
}
/// <summary>
/// 批量添加图片
/// </summary>
/// <param name="pageIndex">页码</param>
/// <param name="fieldName">表单域名称</param>
/// <param name="imageFile">图片文件</param>
/// <param name="rowCount"></param>
/// <param name="colCount"></param>
/// <param name="space"></param>
/// <param name="isScale">是否按比例缩放</param>
/// <param name="isSquare">是否正方形</param>
/// <returns></returns>
public bool PutImageMatrix(int pageIndex, string fieldName, List<string> imageFile, int rowCount, int colCount, int space = 5, bool isScale = true, bool isSquare = false)
{
PdfContentByte pdfContentByte = pdfStamper.GetOverContent(pageIndex);
if (pdfContentByte == null)
{
return false;
}
var positions = pdfFormFields.GetFieldPositions(fieldName);
if (positions.Count == 0)
{
return false;
}
AcroFields.FieldPosition fieldPosition = positions[0];
Rectangle rect = fieldPosition.position;
float left = rect.Left;
float top = rect.Top;
float bottom = rect.Bottom;
float width = rect.Width;
float height = rect.Height;
float cellH = (height - space * (rowCount + 1)) / rowCount;
float cellW = (width - space * (colCount + 1)) / colCount;
int index = 0;
for (int row = rowCount - 1; row >= 0; row--)
{
float posBotton = bottom + (cellH + space) * row + space;
for (int col = 0; col < colCount; col++)
{
float posLeft = left + (cellW + space) * col + space;
if (index < imageFile.Count)
{
Image image = Image.GetInstance(imageFile[index]);
if (isScale)
{
image.SetAbsolutePosition(posLeft, posBotton);
image.ScaleAbsolute(cellW, cellH);
}
else
{
Single imageWidth = image.Width;
Single imageHeight = image.Height;
if (isSquare)
{
imageWidth = Math.Min(image.Width, image.Height);
imageHeight = Math.Min(image.Width, image.Height);
}
Rectangle rectDst = new Rectangle(0, 0, 0, 0);
rectDst.Left = posLeft;
rectDst.Right = posLeft + cellW;
rectDst.Bottom = posBotton;
rectDst.Top = posBotton + cellH;
Rectangle rect1 = GetValidRect(rectDst, imageWidth, imageHeight);
image.SetAbsolutePosition(rect1.Left, rect1.Bottom);
image.ScaleAbsolute(rect1);
}
pdfContentByte.AddImage(image);
}
index++;
}
}
return true;
}
/// <summary>
/// 添加图片
/// </summary>
/// <param name="pageIndex">页码</param>
/// <param name="fieldName">表单域名称</param>
/// <param name="imageFile">图片文件</param>
/// <param name="isScale">是否缩放</param>
/// <returns></returns>
public bool PutImage(int pageIndex, string fieldName, string imageFile, bool isScale = true)
{
PdfContentByte pdfContentByte = pdfStamper.GetOverContent(pageIndex);
if (pdfContentByte == null)
{
return false;
}
var positions = pdfFormFields.GetFieldPositions(fieldName);
if (positions.Count == 0)
{
return false;
}
AcroFields.FieldPosition fieldPosition = positions[0];
Rectangle rectDst = fieldPosition.position;
Image image = Image.GetInstance(imageFile);
if (isScale)
{
image.SetAbsolutePosition(rectDst.Left, rectDst.Bottom);
image.ScaleAbsolute(rectDst);
}
else
{
Single imageWidth = image.Width;
Single imageHeight = image.Height;
Rectangle rect = GetValidRect(rectDst, imageWidth, imageHeight);
image.SetAbsolutePosition(rect.Left, rect.Bottom);
image.ScaleAbsolute(rect);
}
pdfContentByte.AddImage(image);
return true;
}
/// <summary>
/// 添加文本内容
/// </summary>
/// <param name="fieldName">表单域名称</param>
/// <param name="str">文本内容</param>
/// <returns></returns>
public bool PutText(string fieldName, string str)
{
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
BaseFont simheiBase = BaseFont.CreateFont("D:\\Windows\\Fonts\\SIMSUN.TTC,1", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
pdfFormFields.AddSubstitutionFont(simheiBase);
pdfFormFields.SetField(fieldName, str);
return true;
}
Rectangle GetValidRect(Rectangle rectDst, Single imageWith, Single imageHeight)
{
Rectangle rect = new Rectangle(0, 0);
double dRatio0 = ((double)rectDst.Width) / rectDst.Height;
double dRatio1 = ((double)imageWith) / imageHeight;
double ratio = 0;
if (dRatio1 > dRatio0)
{
ratio = ((double)rectDst.Width) / imageWith;
double realHeight = imageHeight * ratio;
double diffHeight = (rectDst.Height - realHeight) / 2;
rect.Left = rectDst.Left;
rect.Top = (float)(rectDst.Top - diffHeight);
rect.Right = rectDst.Right;
rect.Bottom = (float)(rectDst.Bottom + diffHeight);
}
else
{
ratio = ((double)rectDst.Height) / imageHeight;
double realWidth = imageWith * ratio;
double diffWidth = (rectDst.Width - realWidth) / 2;
rect.Left = (float)(rectDst.Left + diffWidth);
rect.Top = rectDst.Top;
rect.Right = (float)(rectDst.Right - diffWidth);
rect.Bottom = rectDst.Bottom;
}
return rect;
}
}
}