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;
}
}
}