应用场景:将用户所填数据填入pdf模板中并生成pdf
使用word制作模板,然后转为pdf;使用【万兴PDF】工具在需要录入的地方添加文本域(该工具可以自动在录入空白处生成文本域,非常nice)。
目前实验通了普通文本框,复选框、Table(列表文本域)。辅助类代码如下:
using iTextSharp.text;
using iTextSharp.text.pdf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;namespace PDFTest
{
public class PdfHelp
{private string fontname = $@"D:\Test\simsun.ttc,0";//字体宋体
//string fontname = $@"D:\Test\simhei.ttf";//黑体
/// <summary>
/// 根据模板生成pdf
/// </summary>
/// <param name="pdfTemplate">模板路径</param>
/// <param name="tempFilePath">输出路劲</param>
/// <param name="parameters">文本域及值 key为文本域名称 value为需要填入的值</param>
public bool CreatePdfByModule(string pdfTemplate, string tempFilePath, Dictionary<string, object> parameters)
{
if (!File.Exists(pdfTemplate))
{
return false;
}
PdfReader pdfReader = null;
PdfStamper stamp = null;
MemoryStream stream = null;
try
{
//获取中文字体
BaseFont baseFont = BaseFont.CreateFont(fontname, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//读取模板文件
pdfReader = new PdfReader(pdfTemplate);
//创建文件流用来保存填充模板后的文件
stream = new MemoryStream();
stamp = new PdfStamper(pdfReader, stream);
AcroFields form = stamp.AcroFields;
//表单文本框是否锁定
stamp.FormFlattening = true;
//填充表单,para为表单的一个(属性-值)字典
foreach (KeyValuePair<string, object> parameter in parameters)
{
if (parameter.Key.Contains("table") && parameter.Value is TableModel)
{
CreateTable(stamp, form, baseFont, parameter.Value as TableModel);
}
else
{
//复选框 Yes 选中
//要输入中文就要设置域的字体;
form.SetFieldProperty(parameter.Key, "textfont", baseFont, null);
//为需要赋值的域设置值;
form.SetField(parameter.Key, parameter.Value.ToString());
}
}
stamp.Close();
stream.Position = 0;
File.WriteAllBytes(tempFilePath, stream.ToArray());
return true;
}
catch (Exception ex)
{
return false;
}
finally
{
if (pdfReader != null) {
pdfReader.Close();
pdfReader = null;
}
if (stamp != null)
{
stamp.Close();
stamp = null;
}
if (stream != null)
{
stream.Close();
stream = null;
}
}
}/// <summary>
/// 在table表中写入数据
/// </summary>
/// <param name="stamp"></param>
/// <param name="form"></param>
/// <param name="baseFont"></param>
/// <param name="tmmodel"></param>
void CreateTable(PdfStamper stamp, AcroFields form, BaseFont baseFont, TableModel tmmodel)
{
// 取到文本域的位置
float[] tablePos = form.GetFieldPositions(tmmodel.TableName);
if (tablePos == null) return;
int pageNo = (int)tablePos[0];
float tableX = tablePos[1];
float tableY = tablePos[4];
PdfContentByte under = stamp.GetOverContent(pageNo);
//确定列数
int count = tmmodel.TableColumsWidth.Length;
//设置列头count代表有几列
PdfPTable tableRow_1 = new PdfPTable(count);
//列头的样式
var FontStyle = new Font(baseFont, 14, 1)
{
Color = new BaseColor(System.Drawing.Color.Black), //设置字体颜色
};
//每个表格的宽度
tableRow_1.SetWidths(tmmodel.TableColumsWidth);
//表格总宽
tableRow_1.TotalWidth = tmmodel.TotalWidth;
tableRow_1.LockedWidth = true;
tableRow_1.KeepTogether = true;
tableRow_1.SplitLate = false;
tableRow_1.SplitRows = true;
var FontStyle_content = new Font(baseFont, 12)
{
Color = new BaseColor(System.Drawing.Color.Black), //设置字体颜色
};
for (int i = 0; i < tmmodel.TableList.Count; i++)
{
tableRow_1.DefaultCell.Border = Rectangle.NO_BORDER;
tableRow_1.DefaultCell.MinimumHeight = 40f;
foreach (var q in tmmodel.TableList[i])
{
var value = q;
//创建表格内属性,这里用了个三元表达是为了把标题的样式区分出来
var para = new Paragraph(value, i == 0 ? FontStyle : FontStyle_content);
para.Alignment = Element.ALIGN_CENTER;//设置居中
var cell = new PdfPCell();
cell.AddElement(para);
//增加Cell
tableRow_1.AddCell(cell);
}
}
tableRow_1.TotalWidth = tmmodel.TotalWidth;
//写入表格 后面的属性不大清除,tablex,tabley应该是表格定位的起点
tableRow_1.WriteSelectedRows(0, -1, tableX, tableY, under);
}/// <summary>
/// 输出模板中定义的文本域
/// </summary>
/// <param name="pdfTemplate"></param>
public void OutPutModuleFilds(string pdfTemplate)
{
PdfReader pdfReader = null;
PdfStamper stamp = null;
MemoryStream stream = null;
try
{//读取模板文件
pdfReader = new PdfReader(pdfTemplate);
//创建文件流用来保存填充模板后的文件
stream = new MemoryStream();
stamp = new PdfStamper(pdfReader, stream);
AcroFields form = stamp.AcroFields;
foreach (var item in form.Fields)
{
Console.WriteLine($"[\"{item.Key}\"]=\"{DateTime.Now.ToString("yyyyMMddHHmmssfffff")}\",");
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (pdfReader != null)
{
pdfReader.Close();
pdfReader = null;
}
if (stamp != null)
{
stamp.Close();
stamp = null;
}
if (stream != null)
{
stream.Close();
stream = null;
}
}
}
}public class TableModel
{
/// <summary>
/// 每列占比
/// </summary>
public float[] TableColumsWidth { get; set; }
/// <summary>
/// table数据,第一行为标题列
/// </summary>
public List<string[]> TableList { get; set; }
/// <summary>
/// 总宽度
/// </summary>
public int TotalWidth { get; set; }
/// <summary>
/// 文本域table的名称
/// </summary>
public string TableName { get; set; }
}
}
调用代码如下:
string pdfTemplate = @"D:\模板table.pdf";
string tempFilePath = $@"D:输出.pdf";
List<string[]> TableList = new List<string[]>();
TableList.Add(new string[] { "序号", "姓名", "性别", "出生年月", "学位", "职称", "工作单位", "项目分工" });
TableList.Add(new string[] { "序号", "姓名", "性别", "出生年月", "学位", "职称", "工作单位", "项目分工" });
TableModel tableModel = new TableModel()
{
TableColumsWidth = new float[] { 20f, 40f, 30f, 40f, 50f, 40f, 110f, 40f },
TotalWidth=700,
TableList= TableList,
TableName="table"
};
Dictionary<string, object> parameters = new Dictionary<string, object>()
{
["课题编号"] = "2023102015122713729",
["实验室_check2"] = "Yes",//复选框
["table"]= tableModel//table};
PdfHelp pdfHelp = new PdfHelp();
bool res= pdfHelp.CreatePdfByModule(pdfTemplate, tempFilePath, parameters);
Console.WriteLine($"完成:{res.ToString()}");
一些注意点:
1、模板文件、输出文件夹、字体文件均需要赋予相关windows操作权限。