1、目标

  在pdf中生成一个可变表头的表格,并向其中填充数据。通过泛型动态的生成表头,通过反射动态获取实体类(我这里是User)的get方法动态获得数据,从而达到动态生成表格。

  每天生成一个文件夹存储生成的pdf文件(文件夹的命名是年月日时间戳),如:20151110

  生成的文件可能在毫秒级别,故文件的命名规则是"到毫秒的时间戳-uuid",如:20151110100245690-ece540e5-7737-4ab7-b2d6-87bc23917c8c.pdf

  通过读取properties文件动态获取文件存储的跟目录。获取方式可查看:

2、所需的jar

  这里通过itex插件进行pdf的生成,需要的jar包括以下几个

java 解析pdf 忽略水印 java解析pdf表格_java

3、编码实现

1)、实体类



package com.zcr.until;

public class User 
{
    private String name;
    private int age ;
    private float height;
    private String adress;
    private String sex;
    private String jj;
    
    public String getJj()
    {
        return jj;
    }

    public void setJj(String jj)
    {
        this.jj = jj;
    }

    public User()
    {
    
    }

    public User(String name,int age,float height,String adress,String sex,String jj)
    {
        this.name = name;
        this.age = age;
        this.height = height;
        this.adress = adress;
        this.sex = sex;
        this.jj = jj;
    }
    
    public String getAdress()
    {
        return adress;
    }

    public void setAdress(String adress)
    {
        this.adress = adress;
    }

    public String getSex()
    {
        return sex;
    }

    public void setSex(String sex)
    {
        this.sex = sex;
    }

    
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public float getHeight() {
        return height;
    }
    public void setHeight(float height) {
        this.height = height;
    }
    
}



2)、properties文件



pdfPath=E\:/appDataPdf



3)、读取properties文件,获取pdf存储的路径



package com.zcr.until;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class GetFilePlace 
{
    /**
     * 读取文件,获取excel保存的根目录
     * @return  excel保存的根目录
     */
    public   String getFilePath()
    {
        String dir = System.getProperty("user.dir");  //获得tomcat所在的工作路径  
        
        //获取到存储了文件存储位置的filedir.properties 文件路径   --->java Project的文件路径
        String realDir = dir + File.separator + "src" + File.separator +"META-INF" + File.separator + "filedir.properties";
        
     //Web project存储路径
        /*String realDir = dir.substring(0, dir.length()-4) + File.separator +"webapps" + File.separator + "generateExcels" 
                      + File.separator + "classes" + File.separator + "META-INF" + File.separator + "config" + File.separator + "filedir.properties";
    */
        return realDir;
    }
    
    /**
     * 获取filePath路径【properities文件】中key对应的值,
     * @param filePath properities文件路径【包含properities文件】
     * @param key 要查找的key值
     * @return key对应的value
     */
     public   String GetValueByKey(String filePath, String key) 
     {
         Properties pps = new Properties();
         try {
              InputStream in = new BufferedInputStream (new FileInputStream(filePath));  
              pps.load(in);
             String value = pps.getProperty(key);
             in.close();
             return value;
             
         }catch (IOException e) {
             e.printStackTrace();
             return null;
         }
     }
    
    /**
     * 查询properities文件中可以对应的存储地点
     * @param key 查询主键
     * @return    key对应的存储地址
     */
    public  String getFileDirFromProperties(String key)
    {
        return GetValueByKey(getFilePath(),key);
    }

}



4)、获取当天存在的文件路径,不存在则生成一个新的文件夹



package com.zcr.service;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Calendar;

public class GenerateFold
{
    /**
     * 查询当前生成的excel需要存在在哪个路径,如果存在则存储在相应的位置,否则生成改目录, 每天生成一个文件夹,文件夹的命名规则为 年月日的时间戳
     * @param foldName  生成excel保存路径
     * @return            现在的excel需要保存路径
     */
    public  String getFold(String foldName)
    {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        
        String todayStr = format.format(Calendar.getInstance().getTime());
        
        String foldPath = foldName + File.separator + todayStr; 
        
        File file = new File(foldPath);
        
        if(!file.exists() && !file.isDirectory())
        {
            System.out.println("不存在");
            file.mkdirs();
        }
        else
        {
            System.out.println("存在");
        }
        return  foldPath;
    }

}



5)、生成文件的名字



package com.zcr.until;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.UUID;

/**
 * 生成文件名字
 * @author zcr
 *
 */
public class GenerateFileName
{
    /**
     * 根据文件类别生成文件的名字,文件的命名规则是:文件目录/生成时间-uuid(全球唯一编码).文件类别
     * @param fileDir  文件的存储路径
     * @param fileType 文件的类别
     * @return                 文件的名字  
     */
    public String generateFileName(String fileDir,String fileType)
    {
        String saveFileName = "";
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSS");
        saveFileName += format.format(Calendar.getInstance().getTime());
        
        UUID uuid = UUID.randomUUID();  //全球唯一编码
        
        saveFileName += "-" + uuid.toString();
        saveFileName += "." + fileType;
        
        saveFileName = fileDir + File.separator + saveFileName;
        
        return saveFileName;
    }
}



6)、生成pdf



package com.zcr.service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.PageSize;
import com.lowagie.text.Phrase;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;
import com.zcr.until.GenerateFileName;
import com.zcr.until.GetFilePlace;
import com.zcr.until.User;

/**
 * 生成pdf
 * @author zcr
 * 
 */
public class CreatePdf
{
    Document document = new Document();// 建立一个Document对象

    private static Font headfont;// 设置字体大小
    private static Font keyfont;// 设置字体大小
    private static Font textfont;// 设置字体大小

    static
    {
        //中文格式
        BaseFont bfChinese;
        try
        {
            // 设置中文显示
            bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);
            headfont = new Font(bfChinese, 10, Font.BOLD);// 设置字体大小
            keyfont = new Font(bfChinese, 8, Font.BOLD);// 设置字体大小
            textfont = new Font(bfChinese, 8, Font.NORMAL);// 设置字体大小
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    
    /**
     * 文成文件
     * @param file 待生成的文件名
     */
    public CreatePdf(File file)
    {
        document.setPageSize(PageSize.A4);// 设置页面大小
        try
        {
            PdfWriter.getInstance(document, new FileOutputStream(file));
            document.open();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    
    public CreatePdf()
    {
        
    }
    
    public void initFile(File file)
    {
        document.setPageSize(PageSize.A4);// 设置页面大小
        try
        {
            PdfWriter.getInstance(document, new FileOutputStream(file));
            document.open();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    

    int maxWidth = 520;
    
    /**
     * 为表格添加一个内容
     * @param value           值
     * @param font            字体
     * @param align            对齐方式
     * @return                添加的文本框
     */
    public PdfPCell createCell(String value, Font font, int align)
    {
        PdfPCell cell = new PdfPCell();
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(align);
        cell.setPhrase(new Phrase(value, font));
        return cell;
    }
    
    /**
     * 为表格添加一个内容
     * @param value           值
     * @param font            字体
     * @return                添加的文本框
     */
    public PdfPCell createCell(String value, Font font)
    {
        PdfPCell cell = new PdfPCell();
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setPhrase(new Phrase(value, font));
        return cell;
    }

    /**
     * 为表格添加一个内容
     * @param value           值
     * @param font            字体
     * @param align            对齐方式
     * @param colspan        占多少列
     * @return                添加的文本框
     */
    public PdfPCell createCell(String value, Font font, int align, int colspan)
    {
        PdfPCell cell = new PdfPCell();
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(align);
        cell.setColspan(colspan);
        cell.setPhrase(new Phrase(value, font));
        return cell;
    }
    
    /**
     * 为表格添加一个内容
     * @param value           值
     * @param font            字体
     * @param align            对齐方式
     * @param colspan        占多少列
     * @param boderFlag        是否有有边框
     * @return                添加的文本框
     */
    public PdfPCell createCell(String value, Font font, int align, int colspan,
            boolean boderFlag)
    {
        PdfPCell cell = new PdfPCell();
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(align);
        cell.setColspan(colspan);
        cell.setPhrase(new Phrase(value, font));
        cell.setPadding(3.0f);
        if (!boderFlag)
        {
            cell.setBorder(0);
            cell.setPaddingTop(15.0f);
            cell.setPaddingBottom(8.0f);
        }
        return cell;
    }

    /**
     * 创建一个表格对象
     * @param colNumber  表格的列数
     * @return              生成的表格对象
     */
    public PdfPTable createTable(int colNumber)
    {
        PdfPTable table = new PdfPTable(colNumber);
        try
        {
            table.setTotalWidth(maxWidth);
            table.setLockedWidth(true);
            table.setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getDefaultCell().setBorder(1);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return table;
    }

    public PdfPTable createTable(float[] widths)
    {
        PdfPTable table = new PdfPTable(widths);
        try
        {
            table.setTotalWidth(maxWidth);
            table.setLockedWidth(true);
            table.setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getDefaultCell().setBorder(1);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return table;
    }

    public PdfPTable createBlankTable()
    {
        PdfPTable table = new PdfPTable(1);
        table.getDefaultCell().setBorder(0);
        table.addCell(createCell("", keyfont));
        table.setSpacingAfter(20.0f);
        table.setSpacingBefore(20.0f);
        return table;
    }

    public <T> void generatePDF(String [] head,List<T> list,int colNum) 
    {
        Class classType = list.get(0).getClass();
        
        // 创建一个只有5列的表格
        PdfPTable table = createTable(colNum);

        // 添加备注,靠左,不显示边框
        table.addCell(createCell("APP信息列表:", keyfont, Element.ALIGN_LEFT, colNum,false));
        
        //设置表头
        for(int i = 0 ; i < colNum ; i++)
        {
            table.addCell(createCell(head[i], keyfont, Element.ALIGN_CENTER));
        }
        
        
        if(null != list && list.size() > 0)
        {
            int size = list.size();
            for(int i = 0 ; i < size ; i++)
            {
                T t = list.get(i);
                for(int j = 0 ; j < colNum ; j ++)
                {
                    //获得首字母
                    String firstLetter = head[j].substring(0,1).toUpperCase(); 
                    
                    //获得get方法,getName,getAge等
                    String getMethodName = "get" + firstLetter + head[j].substring(1);
                   
                    Method method;
                    try
                    {
                        //通过反射获得相应的get方法,用于获得相应的属性值
                        method = classType.getMethod(getMethodName, new Class[]{});
                        try
                        {
                             System.out.print(getMethodName +":" + method.invoke(t, new Class[]{}) +",");
                             //添加数据
                             table.addCell(createCell(method.invoke(t, new Class[]{}).toString(), textfont));
                        }
                        catch (IllegalArgumentException e)
                        {
                            e.printStackTrace();
                        }
                        catch (IllegalAccessException e)
                        {
                            e.printStackTrace();
                        }
                        catch (InvocationTargetException e)
                        {
                            e.printStackTrace();
                        }  
                    }
                    catch (SecurityException e)
                    {
                        e.printStackTrace();
                    }
                    catch (NoSuchMethodException e)
                    {
                        e.printStackTrace();
                    }
                }
                
                System.out.println("");
            }
        }
        
        try
        {
            //将表格添加到文档中
            document.add(table);
        }
        catch (DocumentException e)
        {
            e.printStackTrace();
        }
        
        //关闭流
        document.close();
    }
    
    
    /**
     * 提供外界调用的接口,生成以head为表头,list为数据的pdf
     * @param head  //数据表头
     * @param list  //数据
     * @return        //excel所在的路径
     */
    public <T> String generatePDFs(String [] head,List<T> list)
    {
        final String FilePath = "pdfPath";
        String saveFilePathAndName = "";
    
        //获得存储的根目录
        String savePath = new GetFilePlace().getFileDirFromProperties(FilePath);
        
        //获得当天存储的路径,不存在则生成当天的文件夹
        String realSavePath = new GenerateFold().getFold(savePath);
        
        saveFilePathAndName = new GenerateFileName().generateFileName(realSavePath,"pdf");
        
        File file = new File(saveFilePathAndName);
        try
        {
            file.createNewFile();
        }
        catch (IOException e1)
        {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
            initFile(file);
        try
        {
            file.createNewFile();  //生成一个pdf文件
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        new CreatePdf(file).generatePDF(head,list,head.length);
        
        return saveFilePathAndName;
    }

}



7)、测评函数



public static void main(String[] args) 
    {
        System.out.println("begin");
        
        String [] head = {"name","sex","adress","height","age","jj"};
        
        List<User> list = new ArrayList<User>();
        User user1 = new User("zhangsan",1,1.1f,"北京","男","AA");
        User user2 = new User("lisi",22222,3.2f,"上海","女","BB");
        
        list.add(user1);
        list.add(user2);
        
        
        String filePath = new CreatePdf().generatePDFs(head,list);
        System.out.println(filePath);
        System.out.println("end");
    }



8)、测试结果

java 解析pdf 忽略水印 java解析pdf表格_java_02

9)、文件内容如下

java 解析pdf 忽略水印 java解析pdf表格_文件路径_03

 

  致谢:感谢您的阅读!