PDF空模板填充数据+WPF预览PDF

现在需要一个新需求,使用一个空的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预览,目前已经实现了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值