itext使用模板生成pdf文件_itext 通过 pdf 模板生成 pdf,动态列表-程序员宅基地

技术标签: exception  Java  file  string  methods  adobe  interface  

用pdf模板生成pdf文档很简单,首先需要手动做个pdf模板,上面有很多的类似html里的text域的东西,

给他们起好名字,在程序里填充就可以了。虽然由于不会做模板(实际上由于短时间无法去熟悉使用Adobe Acrobat )

而没有用到此篇文章(转载的别人的)(只好手动生成),但是感觉写的还是不错的。贴出来,以便将来用到了查看。

首先要定义一个DataBean接口,代码如下:

public interface DataBean {  

它是空的,表示是一个存储数据的接口,你也可以不要它,但是面向接口编程是个好的习惯。

将来就用它里面的数据来填充pdf表单。

比如说你有一个pdf模板文件,假设要一个字段xm,代码如下:

public class DataBeanImpl implements DataBean  
{  
    private String  xm;  
  
    public String getXm() {  
        return xm;  
    }  
    public void setXm(String xm) {  
        this.xm = xm;  
    }  
}  

下面就要进行pdf处理了,第一个方法是根据一个模板文件和databean生成一个pdf文件,代码如下:

/** 
 * 根据一个databean,处理一个pdf文件, 
 * @param templatefile //模板文件路径 
 * @param destfile     //目标文件路径 
 * @param databean     //数据接口的实现  
 */  
public void getPdfFile(String templatefile,String destfile,DataBean databean)throws IOException, DocumentException{  
    String TemplatePDF=templatefile;  
    PdfReader reader = new PdfReader(TemplatePDF);  
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destfile));  
    AcroFields form = stamper.getAcroFields(); 
    DataBean db = databean;  
    List<String> fieldnames = this.getFieldName(db); 
    for(int i=0;i<fieldnames.size();i++){  
        String tmpname = fieldnames.get(i);  
        String value = this.getFieldValue(tmpname, db);  
        form.setField(tmpname, value);  
    }   
    stamper.setFormFlattening(true);  
    stamper.close();          
}   

 这个方法中用到两个方法,一个是getfieldname,另一个是getfieldvale分别是取databean实现的名字与值,代码如下:

/** 
 * 根据数据bean得到pdf中要写入的textfield的名字 
 * @param db 
 */  
private List<String> getFieldName(DataBean db){  
    List<String> fieldnames = new ArrayList<String>();  
    Field[] fields = db.getClass().getDeclaredFields();  
    for(int i=0;i<fields.length;i++) {  
        String tmpname  = fields[i].getName();  
        fieldnames.add(tmpname); 
    }  
    return fieldnames;  
} 

private String getFieldValue(String fieldname,DataBean db)  
{  
    String value="";  
    Method[] methods = db.getClass().getDeclaredMethods();  
    for(int i=0;i<methods.length;i++) {  
        String methodname = methods[i].getName();  
        if (methodname.substring(0,3).toUpperCase().equals("GET") && methodname.substring(3).toUpperCase().equals(fieldname.toUpperCase())) {  
            Method method = methods[i];  
            try {  
                value = (String)method.invoke(db,new Object[] {});  
            } catch (Exception e) { 
                e.printStackTrace();  
            }  
        }  
    }
    return value;  
}

可以看出这几段代码的功能还是比较清晰的,他根据数据模型的属性判断需要往pdf表单中填入哪些内容,这首先当然要求你在

做模板和设计DB类时属性域保持一致。然后遍历这些属性,在遍历时通过遍历get方法和get方法后面的字符串找到属性具体的值。

这样就可以以值对的形式将DB的内容输出到pdf表单中。

form.setField(tmpname, value);

上面的代码可以封装在一个类中,可以把他看成是一个“打印公共类”,而对于不同的表单你还可能需要写一个单独的操作类

来准备数据,你很有可能会查询数据库,然后调用DB的set方法。


按说程序写到这应该就行了,但要是有多页呢,应该如何处理呢?于是就又写了个方法:

/** 
 * 根据一组databean,生成一个pdf,生成方法,是将多个pdf合并 
 * @param templatefile 
 * @param destfile 
 * @param databean 
 */  
public void getPdfFile(String templatefile,String destpath,String destfilename,List<DataBean> databean) throws IOException, DocumentException {  
    String filename=destpath+"/"+destfilename;  
    Document document = new Document();  
    PdfCopy copy = new PdfCopy(document, new FileOutputStream(filename));   
    document.open();  
    for (int i=0;i<databean.size();i++) {  
        String tmppdffile = destpath+"/tmp_"+destfilename;  
        this.getPdfFile(templatefile,tmppdffile,databean.get(i));  
        PdfReader reader = new PdfReader(tmppdffile);     
           int n = reader.getNumberOfPages();     
           for(int j=1; j<=n; j++) {     
               document.newPage();      
               PdfImportedPage page = copy.getImportedPage(reader, j);     
               copy.addPage(page);     
           }              
    }  
    //删除临时文件  
    File file =new File(destpath+"/tmp_"+destfilename);  
    if (file.exists()){
        file.delete();  
    }
    document.close();  
}  
个人觉得这个方法可能会有些问题,所有的DB都是用相同的模板个目标路径。而每个处理DB的循环,

都用从头复制?总之是极为混乱的一个方法,

我们的疑问是:一个pdf模板不可以有多页吗?只要一个DB里的内容能跟表单里的所有内容一致应该就可以了。


等用到了将来再说吧。



版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/flyfeifei66/article/details/6739957

智能推荐

求1+2+......+100的和_请编写代码实现:计算从1+2+...+50的和-程序员宅基地

文章浏览阅读2.6k次。如何求1+2+…+100的和?有很多方法,这里我介绍用三种循环方法去求1+2+…+100的和方法一:for循环:代码如下:/** 1. 求1+2+......+100的和 2. 方法1:for循环 */public class Demo2 { public static void main(String[] args) { int sum = 0; ..._请编写代码实现:计算从1+2+...+50的和

HDU - 2121 Ice_cream’s world II 无根最小树形图-程序员宅基地

文章浏览阅读76次。HDU - 2121 :http://acm.hdu.edu.cn/showproblem.php?pid=2121比较好的朱刘算法blog:https://blog.csdn.net/txl199106/article/details/62045479题意:  在一个有向图中,找一个点,使得这个点到其他点的距离和最小,输出距离和,和这个点的坐标。思路:  无根最小树形图,设...

数字孪生系统的好处-程序员宅基地

文章浏览阅读281次。2. 降低成本:数字孪生系统可以帮助企业找到更有效的方式来管理和维护其设备,并帮助设计更高效的制造流程,从而实现成本降低。总的来说,数字孪生系统将为企业带来更高的生产效率、更低的成本和更高的产品质量,帮助企业更好地应对市场挑战并实现业务增长。5. 减少停机时间:数字孪生系统可以帮助企业预测设备停机时间并计划维修,从而最小化设备停机时间。数字孪生系统可以帮助企业识别设备或系统可能出现故障或需要维修的问题,从而提高设备的可靠性。

二十四:RDD源码分析_each rdd is character源码-程序员宅基地

文章浏览阅读238次。一:初始Spark:进入官网 http://spark.apache.orgApache Spark is a unified analytics engine for large-scale data processingApache Spark是一个标准的大型数据处理分析引擎,具有如下4个特性:1.1:运行速度快:相对于hadoop:编程模型不一样:mapreduce是基于进程计算..._each rdd is character源码

angular属性绑定和[disabled]属性来实现简单的输入框验证_angular [disabled] 属性-程序员宅基地

文章浏览阅读5.7k次。使用场景一个输入框和一个提交按钮,当输入框为空时提交按钮不可用。 2.方法angular属性绑定和disabled属性。[(ngModel)]是双向绑定。Html这里就已经可以实现输入框为空时button不可用,但是在浏览器里,简单的篡改button的disable属性就可以绕过这个验证,进一步需要js验证。Ts注:这个comment是预定义的对象。其实..._angular [disabled] 属性

分治---二分搜索,棋盘覆盖_算法设计与分析棋盘覆盖二分搜索-程序员宅基地

文章浏览阅读850次。参考http://blog.csdn.net/liufeng_king/article/details/84778681、分治法分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相同。递归的解这些子问题,然后将各子问题的解合并得到原问题的解。 分治法所能解决的问题一般具有以下几个特征:  1) 该问题的规模缩小到一_算法设计与分析棋盘覆盖二分搜索

随便推点

S275智慧煤矿4G物联网网关:矿山开采的未来已来-程序员宅基地

文章浏览阅读527次,点赞10次,收藏9次。S275是钡铼技术有限公司推出的远程RTU控制终端,支持8路DI/4路DO/6路AI,集成4G全网通模块以及以太网模块,支持双卡,自带多种IO口,1路RS485可用于扩展,实现工业现场数据接入第三方SCADA软件、PLC、HMI设备,也可接入钡铼物联云平台,通过云短信、微信、APP、Web界面直接远程监测、管理、设置远程终端,从而实现对远程工业现场的监控。AI,24位高精度,兼容0~5VDC,0~20mA,4~20mA变送器输入。7、系统操作简单,运行稳定,远程维护,可定制或二次开发。

管理页面的home_CHFS 打造出自己的web文件管理服务-程序员宅基地

文章浏览阅读2.5k次。介绍CuteHttpFileServer/chfs是一个免费的、HTTP协议的文件共享服务器,使用浏览器可以快速访问。它具有以下特点:单个文件,整个软件只有一个可执行程序,无配置文件等其他文件跨平台运行,支持主流平台:Windows,Linux和Mac界面简洁,简单易用支持扫码下载和手机端访问,手机与电脑之间共享文件非常方便支持账户权限控制和地址过滤支持快速分享文字片段支持webdav协..._chfs去广告

欧陆词典导入词典库(自定义英文词典)_如何自定义英语词典-程序员宅基地

文章浏览阅读1.9w次,点赞7次,收藏27次。注: 欧陆词典很强大,一个手机app,可以导入牛津、柯林斯、朗文等很多词典库。在打开欧陆词典后,在手机上看到不认识的英文单词时,只需复制这个英文单词,欧陆词典就会自动弹窗出这个英文单词的意思,很方便。一,如何安装自定义词典http://www.francochinois.com/support/install_extra_dict.html 欧陆词典给的关于如何安装自定义词典的链..._如何自定义英语词典

关于设置CNAME记录的问题-程序员宅基地

文章浏览阅读712次。最近在设置域名时遇到一些问题,上网查了下,发现很多人对CNAME记录认识不清楚,很多论坛包括一些人的回答也是含糊不清,我也是花了很多时间才算是弄清楚,在些想和大家分享下,以免以后有类似问题的再有困惑!CNAME记录也称别名记录,通俗一点说就是一个IP地址的另一个名字,通过除原域名之外的另一个域名或子域名来访问原来的网站。注意!CNAME记录指向的域名或者子域名必须有相应的A记..._cname记录值不知道

linux cpu使用率500%,Linux:CPU使用率100%排查方法-程序员宅基地

文章浏览阅读1.7k次。Linux做为一个多任务操做系统,将每一个CPU的时间划分为很短的时间片,再经过调度器轮流分配给各个任务使用,所以形成多任务同时运行的错觉。CPU使用率Linux做为一个多任务操做系统,将每一个CPU的时间划分为很短的时间片,再经过调度器轮流分配给各个任务使用,所以形成多任务同时运行的错觉。为了维护CPU时间,Linux经过事先定义的节拍率(内核中表示为HZ),触发时间中断,并使用全局变量Jiff..._cpu使用率500%

Web Server Security Best Practices-程序员宅基地

文章浏览阅读1.4k次。From http://www.pcmag.com/article2/0,2817,11525,00.aspEven if you're just a casual site administrator who isn't responsible for safeguarding masses of sensitive corporate data, you need to be co

推荐文章

热门文章

相关标签