itext使用模板生成pdf文件

用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里的内容能跟表单里的所有内容一致应该就可以了。


等用到了将来再说吧。



猜你喜欢

转载自blog.csdn.net/flyfeifei66/article/details/6739957