一、前言
PDF文件在目前来说是比较流行的电子文档格式,在.Net framework 中身并不包含可以和pdf打交道的方法,也没有很好操作PDF的类库,所以我们需要对pdf进行编辑,加密,模板打印等操作不得不去找可用的第三方组件,这里就可以选择使用ITextSharp来实现,这个程序是JAVA工具IText的.Net版本。
准备:
简单的操作直接查看帮助文件,此处先省略 后续考虑补充
二、itextsharp 使用
2.1 pdf模板
本次讲的是根据pdf模板导出数据,首先创建模板,我这里使用的工具是Adobe Acrobat 视图——工具——准备表单,可以在需要赋值的地方放上一个文本框,把名字改成要用的名字。
这是编辑好后的效果
2.2 新建项目
添加引用
新建了一个导出数据测试窗体 load事件以及测试数据,

/// <summary> /// 模拟数据 /// </summary> DataTable dt; private void frmDemo1_Load(object sender, EventArgs e) { #region 模拟数据 dt = new DataTable(); dt.Columns.Add("number", typeof(string)); dt.Columns.Add("name", typeof(string)); dt.Columns.Add("yw", typeof(string)); dt.Columns.Add("sx", typeof(string)); dt.Columns.Add("yy", typeof(string)); dt.Columns.Add("pd", typeof(string)); dt.Columns.Add("pe", typeof(string)); dt.Columns.Add("remark", typeof(string)); DataRow dr = dt.NewRow(); dr["number"] = "1"; dr["name"] = "小明"; dr["yw"] = "95"; dr["sx"] = "90"; dr["yy"] = "75"; dr["pd"] = "80"; dr["pe"] = "90"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["number"] = "2"; dr["name"] = "小红"; dr["yw"] = "100"; dr["sx"] = "90"; dr["yy"] = "85"; dr["pd"] = "100"; dr["pe"] = "90"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["number"] = "3"; dr["name"] = "小芳"; dr["yw"] = "95"; dr["sx"] = "95"; dr["yy"] = "90"; dr["pd"] = "90"; dr["pe"] = "90"; dt.Rows.Add(dr); dataGridView1.DataSource = dt; #endregion }
封装了一个 导出Pdf帮助类
using iTextSharp.text.pdf; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; namespace itextsharpDemo { /// <summary> /// PDF导出类 /// </summary> public class PdfLeadingHelper { /// <summary> /// 根据路径获取模板 /// </summary> /// <param name="pdfTemplate"></param> /// <returns></returns> public static Dictionary<string, string> ReadForm(string pdfTemplate) { Dictionary<string, string> dic = new Dictionary<string, string>(); PdfReader pdfReader = null; try { pdfReader = new PdfReader(pdfTemplate); AcroFields pdfFormFields = pdfReader.AcroFields; foreach (var de in pdfFormFields.Fields) { dic.Add(de.Key, ""); } } catch (Exception ex) { dic = null; //记录日志 注释 // LogHelper.Logger(LogLevel.Error, "pdf导出类发生异常:根据路径获取模板时异常" + ex.ToString(), ex); } finally { if (pdfReader != null) { pdfReader.Close(); } } return dic; } /// /// 向pdf模版填充内容,并生成新的文件 /// /// 模版路径 /// 生成文件保存路径 /// 标签字典(即模版中需要填充的控件列表) public static bool FillForm(string pdfTemplate, string newFile, Dictionary<string, string> dic) { bool rsBool = true; PdfReader pdfReader = null; PdfStamper pdfStamper = null; try { pdfReader = new PdfReader(pdfTemplate); pdfStamper = new PdfStamper(pdfReader, new FileStream( newFile, FileMode.Create)); AcroFields pdfFormFields = pdfStamper.AcroFields; //设置支持中文字体 BaseFont baseFont = BaseFont.CreateFont("C:\\WINDOWS\\FONTS\\STSONG.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); pdfFormFields.AddSubstitutionFont(baseFont); foreach (var de in dic) { pdfFormFields.SetField(de.Key, de.Value + ""); } pdfStamper.FormFlattening = true; } catch (Exception ex) { //记录日志 注释 // LogHelper.Logger(LogLevel.Error, "pdf导出类发生异常:向pdf模版填充内容,并生成新的文件时异常"+ex.ToString(), ex); rsBool = false; } finally { if (pdfStamper != null) { pdfStamper.Close(); } if (pdfReader != null) { pdfReader.Close(); } } return rsBool; } } }
导出按钮事件
private void button1_Click(object sender, EventArgs e) { //dic 获取学生成绩表 Pdf导出模板 string templetPath = System.Environment.CurrentDirectory + @"\学生成绩表.pdf"; Dictionary<string, string> dic = PdfLeadingHelper.ReadForm(templetPath); #region 赋值 dic dic["className"] = textBox1.Text; for (int i = 1; i <= dt.Rows.Count; i++) { if (dic.ContainsKey("number_" + i)) { dic["number_" + i] = dt.Rows[i-1]["number"] +""; dic["name_" + i] = dt.Rows[i-1]["name"] + ""; dic["yw_" + i] = dt.Rows[i-1]["yw"] + ""; dic["sx_" + i] = dt.Rows[i-1]["sx"] + ""; dic["yy_" + i] = dt.Rows[i-1]["yy"] + ""; dic["pd_" + i] = dt.Rows[i-1]["pd"] + ""; dic["pe_" + i] = dt.Rows[i-1]["pe"] + ""; dic["remark_" + i] = dt.Rows[i-1]["remark"] + ""; } } #endregion //保存 SaveFileDialog dlg = new SaveFileDialog(); dlg.FileName = "成绩单"; dlg.DefaultExt = ".pdf"; dlg.Filter = "Text documents (.pdf)|*.pdf"; if (dlg.ShowDialog() == DialogResult.OK) { bool rsBool = PdfLeadingHelper.FillForm(templetPath, dlg.FileName, dic); if (rsBool) { MessageBox.Show("导出成功!!"); } } }
先获取pdf模板变量,Dictionary<string, string> dic 键值对类型
赋值对应dic
保存成新pdf
这样一个小案例就完成了。
2.3 动态数据多页
实现步骤:
1、首先对数据动态导出在一个临时目录
2、然后将此目录文件合并成一个Pdf文件多页效果
3、清空临时目录数据
下方是测试数据

#region 模拟数据 dt = new DataTable(); dt.Columns.Add("number", typeof(string)); dt.Columns.Add("name", typeof(string)); dt.Columns.Add("yw", typeof(string)); dt.Columns.Add("sx", typeof(string)); dt.Columns.Add("yy", typeof(string)); dt.Columns.Add("pd", typeof(string)); dt.Columns.Add("pe", typeof(string)); dt.Columns.Add("remark", typeof(string)); DataRow dr = dt.NewRow(); dr["number"] = "1"; dr["name"] = "小明"; dr["yw"] = "95"; dr["sx"] = "90"; dr["yy"] = "75"; dr["pd"] = "80"; dr["pe"] = "90"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["number"] = "2"; dr["name"] = "小红"; dr["yw"] = "100"; dr["sx"] = "90"; dr["yy"] = "85"; dr["pd"] = "100"; dr["pe"] = "90"; dt.Rows.Add(dr); dr = dt.NewRow(); dr["number"] = "3"; dr["name"] = "小芳"; dr["yw"] = "95"; dr["sx"] = "95"; dr["yy"] = "90"; dr["pd"] = "90"; dr["pe"] = "90"; dt.Rows.Add(dr); for (int i = 1; i < 2000; i++) { dr = dt.NewRow(); dr["number"] = 3 + i; dr["name"] = "测试人员" + (3 + i); dr["yw"] = "95"; dr["sx"] = "95"; dr["yy"] = "90"; dr["pd"] = "90"; dr["pe"] = "90"; dt.Rows.Add(dr); } dataGridView1.DataSource = dt;
下方是合拼PDF方法

/// <summary> 合并PDF </summary> /// <param name="fileList">PDF文件集合</param> /// <param name="outMergeFile">合并文件名</param> public static bool MergePDFFiles(string[] fileList, string outMergeFile) { bool rsBool = true; try { List<PdfReader> readerList = new List<PdfReader>();//记录合并PDF集合 iTextSharp.text.Document document = new iTextSharp.text.Document(iTextSharp.text.PageSize.A4); /*PageSize.A4.Rotate()横向*/ PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(outMergeFile, FileMode.Create)); document.Open(); PdfContentByte cb = writer.DirectContent; PdfImportedPage newPage; for (int i = 0; i < fileList.Length; i++) { if (!string.IsNullOrEmpty(fileList[i])) { PdfReader reader = new PdfReader(fileList[i]); int iPageNum = reader.NumberOfPages; for (int j = 1; j <= iPageNum; j++) { document.NewPage(); newPage = writer.GetImportedPage(reader, j); cb.AddTemplate(newPage, 0, 0); } readerList.Add(reader); } } document.Close(); //释放集合资源 foreach (var rd in readerList) { rd.Dispose(); } } catch (Exception) { rsBool = false; } return rsBool; }
导出按钮下新方法

//dic 获取学生成绩表 Pdf导出模板 string templetPath = System.Environment.CurrentDirectory + @"\学生成绩表.pdf"; //临时目录文件 string temporaryDirectory = System.Environment.CurrentDirectory + @"\DB\TemporaryDirectory\学生成绩表"; SaveFileDialog dlg = new SaveFileDialog(); dlg.FileName = "成绩单"; dlg.DefaultExt = ".pdf"; dlg.Filter = "Text documents (.pdf)|*.pdf"; if (dlg.ShowDialog() == DialogResult.OK) { try { if (Directory.Exists(temporaryDirectory))//判断是否存在文件 { DirectoryInfo dir = new DirectoryInfo(temporaryDirectory);//存在清空文件夹及文件 dir.Delete(true); } Directory.CreateDirectory(temporaryDirectory); int pageValue = 13;//一页多少行数据 int page = Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(dt.Rows.Count) / Convert.ToDecimal(pageValue)));//多少页 for (int i = 1; i <= page; i++) { #region 赋值 dic Dictionary<string, string> dic = PdfLeadingHelper.ReadForm(templetPath); dic["className"] = textBox1.Text + i; for (int j = 1; j <= pageValue; j++) { if (dic.ContainsKey("number_" + j)) { int index = j - 1 + pageValue * (i - 1); if (index + 1 > dt.Rows.Count)//当超过了值 break; #region dic["number_" + j] = dt.Rows[index]["number"] + ""; dic["name_" + j] = dt.Rows[index]["name"] + ""; dic["yw_" + j] = dt.Rows[index]["yw"] + ""; dic["sx_" + j] = dt.Rows[index]["sx"] + ""; dic["yy_" + j] = dt.Rows[index]["yy"] + ""; dic["pd_" + j] = dt.Rows[index]["pd"] + ""; dic["pe_" + j] = dt.Rows[index]["pe"] + ""; dic["remark_" + j] = dt.Rows[index]["remark"] + ""; #endregion } } #endregion #region 保存到临时目录 bool rsBool = PdfLeadingHelper.FillForm(templetPath, temporaryDirectory + @"\成绩单" + i + ".pdf", dic); //if (rsBool) // MessageBox.Show("第 " + i + " 页导出成功!!"); //else // MessageBox.Show("第 " + i + " 页导出异常!!"); #endregion } string[] files = Directory.GetFiles(temporaryDirectory, "*.pdf"); //IComparer fileNameComparer = new FilesNameComparerClass(); //List<string> list = files.ToList(); //files.Sort(fileNameComparer); if (files.Length == 0) { return; } //文件名排序 不加此排序会导致页内容不对 files = files.OrderBy(s => int.Parse(System.Text.RegularExpressions.Regex.Match(Path.GetFileNameWithoutExtension(s), @"\d+").Value)).ToArray(); //合并pdf bool rsBools = PdfLeadingHelper.MergePDFFiles(files, dlg.FileName); if (rsBools) { MessageBox.Show("导出完成!!"); } //删除临时文件 DirectoryInfo di = new DirectoryInfo(temporaryDirectory); di.Delete(true); } catch (Exception ex) { throw; } }
实现完成效果图如下:
本文档很多方法都是网上找的,简单的案例供大家参考下。