现在需要一个新需求,使用一个空的PDF模板然后后台填入数据生成一个PDF文件,且软件可以预览。那原先的写法WPF的打印预览就不符合这个版本了
首先先生成模板文件
使用acrobat编辑一个模板文件在空白位置创建文本域,然后设置了名称之后,就可以通过后台代码对他进行赋值了
然后后台生成PDF文件
定义一个PdfLeadingHelper类,其中需要增加一个ItextSharp的nuget引用
/// <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\\simhei.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
pdfFormFields.AddSubstitutionFont(baseFont);
String[] checkboxstates = pdfFormFields.GetAppearanceStates("CheckBox1");
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;
}
}
直接调用,然后生成为PDF文件
Dictionary<string, string> dic = PdfLeadingHelper.ReadForm(templatePath);
SetDic(dic);//然后在这里对dic进行赋值,我这里就不放具体实现了
if (!PdfLeadingHelper.FillForm(templatePath, tempPdfPath, dic))
{
MessageBox.Show("生成失败");
}
预览
找了好多种方法都无法把PDF文件直接显示到界面上,最后还是通过将PDF转为XPS文件,然后使用之前的WPF的打印预览的方法显示到界面上。
这种方法需要对FreeSpire.PDF进行nuget引用,只有这个是免费的,其他的要么需要收费,要么会出现水印,找了好久才找到
Spire.Pdf.PdfDocument doc = new Spire.Pdf.PdfDocument();
//加载PDF文档
doc.LoadFromFile(tempPdfPath);
doc.SaveToFile(tempXpsPath, Spire.Pdf.FileFormat.XPS);
XpsDocument xpsd = new XpsDocument(tempXpsPath, FileAccess.Read);
pDialog.PrintDocument(xpsd.GetFixedDocumentSequence().DocumentPaginator, "打印报表");
总结
其实这种方法很蠢,只不过是目前的无奈之举,本来是想实现一个用户自定义的PDF编辑器,然后自动定义key跟value显示然后保存为模板,然后就找到一个很好的通过XML定义实现模板的例子MigraDocXML,可惜不支持中文,不然直接使用这个了。
后续我想改为设计一个html的方式实现PDF预览,目前已经实现了