java实现pdf的生成下载打印,java生成pdf电子账单,java生成pdf合同模板

来源:互联网 发布:户外运动大数据 编辑:程序博客网 时间:2024/05/01 02:03

最近公司要做个生成pdf电子账单凭证的功能,由于这个公司没有任何代码可借鉴,这个时候我就必须得自己搞明白具体的每一步应该怎么做,引什么jar包?用什么方式去实现?这篇博客中会给出从头到尾及其详细的代码和工具类以及jar包,方便大家需要时直接粘贴到自己项目中,此功能完成加调试1天即可完成,此案列可以用模板套打的方式完成合同以及账单或是单纯的文案式pdf。下面先给一张最终实现的效果图片。


在看到此图的时候我首先想到两种方案,第一个是直接由java生成pdf,每一行的生成都由java代码控制。第二种使用模板套打的方式,即我有个空白的pdf模板,把需要改变的地方的值置为空白,然后通过程序去写入。很明显第二种方案简单,且效率高。java实现对pdf的编辑用到了itext技术,引用了itext的相关jar包如下:

        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.10</version>
        </dependency>
        <dependency>
        <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>

大家如果不是maven的项目可以去下载相应的jar包。

触发下载pdf的肯定是页面的某个按钮等,jsp页面代码如下:

 function printPDF(outOrderId,serialNumber){//outOrderId,serialNumber 这是参数,可根据自己的项目需求来,window.open默认是get方式,所以参数大家需要注意一下
        window.open("${ctx}/pdf/print?templateName=certificate.pdf&outOrderId="+outOrderId+"&serialNumber="+serialNumber,'_blank',
                'left=0,top=0,width='+ (screen.availWidth - 10) +',height='+ (screen.availHeight-50) +',scrollbars,resizable=yes,toolbar=yes');
    }

window.open方法中就不在此解释了,前面参数是访问后台的url,后面的是打开浏览器的一个新的页面和窗口。

紧跟着代码进入到后台的controller控制层,--------------------------------------------------

    @RequestMapping(value = "/print")
    @ResponseBody
    public void pdfPrint(@RequestParam(required=false,value="templateName") String templateName,
            HttpServletRequest request, HttpServletResponse response,AgentPayDetailInfo agentForm) throws Exception {
    

       //agentPayInfo  这个对象可以根据具体的需求换成你们自己的java对象,Text1-Text13,是pdf模板上空白处的表单的key值,通过该值可以用程序编辑pdf

        //组装模板所需数据HashMap
        HashMap<String, String> mapPDF = new HashMap<String, String>();
        mapPDF.put("Text1", DateUtil.getDateFormatYH(agentPayInfo.getFinishDate()));//交易时间
        mapPDF.put("Text2", Constants.PAY_ONESELF_NAME);//付款方全称
        mapPDF.put("Text3", NumberToCN.number2CNMontrayUnit(agentPayInfo.getAmount()));//金额人民币大写  汉字
        mapPDF.put("Text4", agentPayInfo.getCardholder());//账户名称
        mapPDF.put("Text5", agentPayInfo.getBankCardNo());//银行卡号
        mapPDF.put("Text6", agentPayInfo.getBankName());//开户行
        mapPDF.put("Text7", agentPayInfo.getAmount().toString());////金额人民币小写  数字
        mapPDF.put("Text8", Constants.RMB);//账户类型
        mapPDF.put("Text9", Constants.PAY_CERTIFICATE_TYPE);//交易类型
        mapPDF.put("Text10", "");//用途
        mapPDF.put("Text11", Constants.PAY_CERTIFICATE_REMARK);//备注
        String receiptNumber = DateUtil.getFDate(agentPayInfo.getFinishDate()) + agentPayInfo.getOutOrderId() + agentPayInfo.getSerialNumber();
        mapPDF.put("Text12", "电子回单编号:" + receiptNumber);//电子回单编号
        mapPDF.put("Text13", DateUtil.getFormatDate(agentPayInfo.getFinishDate()));//章子时间
        
        //生成pdf
        pdfStream = this.print(templateName, mapPDF, request);
        
        ServletOutputStream op = response.getOutputStream();
        response.setContentType("application/pdf"); 
        response.setHeader("Content-Disposition", "inline; filename=\""  
                 + new String(receiptNumber.getBytes("gb18030"), "ISO8859-1") + ".pdf" + "\"");   

        int length = 0;
        byte[] bytes = new byte[1024];
        while ((pdfStream != null) && ((length = pdfStream.read(bytes)) != -1)) {
            op.write(bytes, 0, length);
        }
        op.close();
        response.flushBuffer();
    }

    /**
     * 打印,以PDF为模板
     * @param templateName String 模板名字
     * @param map 模板数据HashMap
     * @return InputStream
     * @throws IOException
     */
    private InputStream print(String templateName, HashMap map, HttpServletRequest request) throws IOException {
        InputStream is = null;
        //服务器端PDF模板文件名
        //String merchId = getCurrentUser().getMerchId();
        String realPath = request.getSession().getServletContext().getRealPath("/");
        String web_info_URL = PropertyUtils.getValue("WEB_INFO_URL");
        String agentPayPath = PropertyUtils.getValue("PDF_PATH");
        String url = realPath + web_info_URL + agentPayPath;// pdf
        String templatePath = url + "/model/";//模板路径
        String serverPath = url + "/template/";//临时文件路径
        
        PdfFormater pdf = new PdfFormater(templatePath, serverPath, templateName, map);
        String PdfFilePath = pdf.doTransform();
        is = new FileInputStream(PdfFilePath);
        return is;
    }

------------------------------------------------------------------------------------------------------------------------

输出给页面是用的ServletOutputStream,设置了response的.setContentType("application/pdf"); 文件为pdf,,这种方式下载和打印方法由客户端自己电脑上的flash和浏览器去完成,省去了服务端的一部分功能。

小写数字转化大写汉字 金额的工具类可以网上搜索一个NumberToCN.number2CNMontrayUnit()这个也是我自己从网上搜索的

PdfFormater 类-------------------------

public class PdfFormater {
    //pdf模板和结果路径相关设置
    private String templateDir;

    private String basePath;

    private String templateFileFo;
    
    //需填充数据
    private Map dataMap;

    private String barcodeString;

    private String tempFileName;

    private String resultFileName;
    //动态数据
    private List dynData;

    /**
     * 构造器,生成PDF引擎实例,并引入相应模板文件XXX.FO、路径和报表数据HashMap
     *
     * @param templateDir
     *            模板文件所在目录
     * @param basePath
     *            模板文件工作副本及结果PDF文件所在工作目录
     * @param templateFileFo
     *            模板文件名,推荐格式为“XXXTemplate.FO”, 其文件由word模板文档在设计时转换而成
     * @param dataMap
     *            对应模板的数据HashMap,由调用该打印引擎的里程根据模板格式和约定进行准备
     */
    public PdfFormater(String templateDir, String basePath,
            String templateFileFo, Map dataMap) {
        this.templateDir = templateDir;
        this.basePath = basePath;
        this.templateFileFo = templateFileFo;
        this.dataMap = dataMap;
    }

    private BaseFont getBaseFont(Object obj) {
        // 需要根据不同的模板返回字体
        BaseFont bf = null;
        try {
            /*bf = BaseFont.createFont("simsun.ttf",
                    BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);*/
             bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bf;
    }

    public String doTransform() {
        long name = System.currentTimeMillis();
        tempFileName = "temp" + name + ".pdf";
        resultFileName = "best" + name + ".pdf";

        try {
            PdfReader reader;
            PdfStamper stamper;

            reader = new PdfReader(templateDir + "/" + templateFileFo);
            stamper = new PdfStamper(reader, new FileOutputStream(basePath + "/" + tempFileName));

            AcroFields form = stamper.getAcroFields();
            form.addSubstitutionFont(getBaseFont(""));
            transformRegular(form);
            stamper.setFormFlattening(true);
            stamper.close();

            postProcess();
            //FileOutputStream fos = new FileOutputStream(basePath + "/" + tempFileName);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return basePath + "/" + resultFileName;
    }

    /**
     * 填充规整的表单域
     *
     * @param form
     */
    private void transformRegular(AcroFields form) {
        if (dataMap == null || dataMap.size() == 0)
            return;
        String key = "";
        Iterator ekey = dataMap.keySet().iterator();
        Object obj = null ;
        while (ekey.hasNext()) {
            key = ekey.next().toString();
            try {
                obj = dataMap.get(key);
                if(obj instanceof List)    {
                    //map中放的是list,为动态字段
                    dynData = (List)obj;
                    transformDynTable(form);
                }else{
                    //非空放入
                    if( dataMap.get(key) != null)
                        form.setField(key, dataMap.get(key).toString());
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (DocumentException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 动态table的填充
     * @param form
     */
    private void transformDynTable(AcroFields form) {
        if (dynData == null || dynData.size() == 0)
            return;
        Object obj = null;
        ReflectUtils rutil = new ReflectUtils();
        String name = "";
        String value = "";
        for (int x = 0; x < dynData.size(); x++) {
            obj = dynData.get(x);
            Field[] fld = obj.getClass().getDeclaredFields();
            for (int i = 0; i < fld.length; i++) {
                name = fld[i].getName();
                value = (String) rutil.getFieldValue(obj, name);
                try {
                    form.setField(name + x, value);
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (DocumentException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 对生成的pdf文件进行后处理
     *
     * @throws RptException
     */
    private synchronized void postProcess() throws Exception {
        FileOutputStream fosRslt = null;
        PdfStamper stamper = null;
        try {
            PdfReader reader = new PdfReader(basePath + "/" + tempFileName);

            fosRslt = new FileOutputStream(basePath + "/" + resultFileName);
            stamper = new PdfStamper(reader, fosRslt);

            Rectangle pageSize = reader.getPageSize(1);
            float width = pageSize.getWidth();
            //float height = pageSize.getHeight();
            /*BaseFont bf = BaseFont.createFont("simsun.ttf",
                    BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);*/
            BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);
            /*BaseFont bfComic = BaseFont.createFont("simhei.ttf",
                    BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);*/
            PdfContentByte over;
            int total = reader.getNumberOfPages() + 1;
            for (int i = 1; i < total; i++) {
                over = stamper.getOverContent(i);
                if (total <= 2)    break;
                over.beginText();
                over.setFontAndSize(bf, 10);
                over.setTextMatrix(width - 92f, 32);
                over.showText("第 " + i + " 页");
                over.endText();
            }
        } catch (Exception ie) {
            ie.printStackTrace();
        } finally {
            if (stamper != null) {
                try {
                    stamper.close();
                } catch (DocumentException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fosRslt != null) {
                try {
                    fosRslt.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            File pdfFile = new File(basePath, "/" + tempFileName);
            pdfFile.delete();
        }
    }

}

---------------------------------------------------------------------------------------

本地项目pdf模板路径:

接下来说一下这个模板的问题,我们需要根据需求去自己编辑pdf,而编辑pdf的软件一般是收费的,我这边是用的迅捷PDF编辑器,然后加水印后用AI编辑器删除水印。给大家截图哈还是:


这个章子是一个图片添加进去的,章子的中间是没有日期的,这个中间的日期因为是可变的,所以需要作为一个表单由程序去写入具体的值,在点击编辑内容时,如图所示,右侧有属性什么的,很好使用的。我们看到表单需要填写内容的区域为空白区域,然后我们点击编辑表单按钮出现如图所示的:


域名就是程序中的map的key值,通过这个程序把内容写入到pdf具体的位置,可以设置字体大小,颜色,边框,对齐方式等。

再看一下项目运行后的的效果,在点击某个按钮后,浏览器会弹出个新的窗口如图所示:

好了,模板套打的基本说完了,在PdfFormater类中有些对页数的设置,页眉页脚都可以用类似的方法去实现,合同模板套打的案例我就不给出了。

还有一些本地生成pdf文件的:

public class PDFBillUtil {//(此工具类转载 http://blog.csdn.net/justinytsoft/article/details/53320225)

    public static void createBillPDF(BillPDF billPDF) {
        try {
            // 输出路径
            String outPath = "C:/Users/Administrator/Desktop/Helloworld.PDF";

            // 设置纸张
            Rectangle rect = new Rectangle(PageSize.A4);

            // 创建文档实例
            Document document = new Document(rect);

            PdfWriter.getInstance(document, new FileOutputStream(outPath));

            // 设置字体
            BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            com.itextpdf.text.Font FontChinese24 = new com.itextpdf.text.Font(bfChinese, 24,
                    com.itextpdf.text.Font.BOLD);
            com.itextpdf.text.Font FontChinese18 = new com.itextpdf.text.Font(bfChinese, 18,
                    com.itextpdf.text.Font.BOLD);
            com.itextpdf.text.Font FontChinese16 = new com.itextpdf.text.Font(bfChinese, 16,
                    com.itextpdf.text.Font.BOLD);
            com.itextpdf.text.Font FontChinese12 = new com.itextpdf.text.Font(bfChinese, 12,
                    com.itextpdf.text.Font.NORMAL);
            com.itextpdf.text.Font FontChinese11Bold = new com.itextpdf.text.Font(bfChinese, 11,
                    com.itextpdf.text.Font.BOLD);
            com.itextpdf.text.Font FontChinese11 = new com.itextpdf.text.Font(bfChinese, 11,
                    com.itextpdf.text.Font.ITALIC);
            com.itextpdf.text.Font FontChinese11Normal = new com.itextpdf.text.Font(bfChinese, 11,
                    com.itextpdf.text.Font.NORMAL);

            document.open();
            
            // table1
            PdfPTable table1 = new PdfPTable(3);
            PdfPCell cell11 = new PdfPCell(new Paragraph("费用报销", FontChinese24));
            cell11.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell11.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell11.setBorder(0);
            String imagePath = "D:/111.jpg";
            Image image1 = Image.getInstance(imagePath);

            Image image2 = Image.getInstance(imagePath);
            // 设置每列宽度比例
            int width11[] = { 35, 40, 25 };
            table1.setWidths(width11);
            table1.getDefaultCell().setBorder(0);
            table1.addCell(image1);
            table1.addCell(cell11);
            table1.addCell(image2);
            document.add(table1);
            // 加入空行
            Paragraph blankRow1 = new Paragraph(18f, " ", FontChinese18);
            document.add(blankRow1);

            // table2
            PdfPTable table2 = new PdfPTable(2);
            // 设置每列宽度比例
            int width21[] = { 2, 98 };
            table2.setWidths(width21);
            table2.getDefaultCell().setBorder(0);
            PdfPCell cell21 = new PdfPCell(new Paragraph("报销概要", FontChinese16));
            String imagePath2 = "D:/111.jpg";
            Image image21 = Image.getInstance(imagePath2);
            cell21.setBorder(0);
            table2.addCell(image21);
            table2.addCell(cell21);
            document.add(table2);
            // 加入空行
            Paragraph blankRow2 = new Paragraph(18f, " ", FontChinese18);
            document.add(blankRow2);

            // table3
            PdfPTable table3 = new PdfPTable(3);
            int width3[] = { 40, 35, 25 };
            table3.setWidths(width3);
            PdfPCell cell31 = new PdfPCell(new Paragraph("申请人:" + "XXX", FontChinese11Normal));
            PdfPCell cell32 = new PdfPCell(new Paragraph("日期:" + "2011-11-11", FontChinese11Normal));
            PdfPCell cell33 = new PdfPCell(new Paragraph("报销单号:" + "123456789", FontChinese11Normal));
            cell31.setBorder(0);
            cell32.setBorder(0);
            cell33.setBorder(0);
            table3.addCell(cell31);
            table3.addCell(cell32);
            table3.addCell(cell33);
            document.add(table3);
            // 加入空行
            Paragraph blankRow31 = new Paragraph(18f, " ", FontChinese11);
            document.add(blankRow31);

            // table4
            PdfPTable table4 = new PdfPTable(2);
            int width4[] = { 40, 60 };
            table4.setWidths(width4);
            PdfPCell cell41 = new PdfPCell(new Paragraph("公司:" + "XXX", FontChinese11Normal));
            PdfPCell cell42 = new PdfPCell(new Paragraph("部门:" + "XXX", FontChinese11Normal));
            cell41.setBorder(0);
            cell42.setBorder(0);
            table4.addCell(cell41);
            table4.addCell(cell42);
            document.add(table4);
            // 加入空行
            Paragraph blankRow41 = new Paragraph(18f, " ", FontChinese11);
            document.add(blankRow41);

            // table5
            PdfPTable table5 = new PdfPTable(1);
            PdfPCell cell51 = new PdfPCell(new Paragraph("报销说明:" + "XXX", FontChinese11));
            cell51.setBorder(0);
            table5.addCell(cell51);
            document.add(table5);
            // 加入空行
            Paragraph blankRow51 = new Paragraph(18f, " ", FontChinese18);
            document.add(blankRow51);

            // table6
            PdfPTable table6 = new PdfPTable(2);
            table6.getDefaultCell().setBorder(0);
            table6.setWidths(width21);
            PdfPCell cell61 = new PdfPCell(new Paragraph("报销明细", FontChinese16));
            cell61.setBorder(0);
            table6.addCell(image21);
            table6.addCell(cell61);
            document.add(table6);
            // 加入空行
            Paragraph blankRow4 = new Paragraph(18f, " ", FontChinese16);
            document.add(blankRow4);

            // table7
            PdfPTable table7 = new PdfPTable(6);
            BaseColor lightGrey = new BaseColor(0xCC, 0xCC, 0xCC);
            int width7[] = { 20, 18, 13, 20, 14, 15 };
            table7.setWidths(width7);
            PdfPCell cell71 = new PdfPCell(new Paragraph("费用类型", FontChinese11Bold));
            PdfPCell cell72 = new PdfPCell(new Paragraph("费用发生时间", FontChinese11Bold));
            PdfPCell cell73 = new PdfPCell(new Paragraph("详细信息", FontChinese11Bold));
            PdfPCell cell74 = new PdfPCell(new Paragraph("消费金币/币种", FontChinese11Bold));
            PdfPCell cell75 = new PdfPCell(new Paragraph("报销汇率", FontChinese11Bold));
            PdfPCell cell76 = new PdfPCell(new Paragraph("报销金额", FontChinese11Bold));
            // 表格高度
            cell71.setFixedHeight(25);
            cell72.setFixedHeight(25);
            cell73.setFixedHeight(25);
            cell74.setFixedHeight(25);
            cell75.setFixedHeight(25);
            cell76.setFixedHeight(25);
            // 水平居中
            cell71.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell72.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell73.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell74.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell75.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell76.setHorizontalAlignment(Element.ALIGN_CENTER);
            // 垂直居中
            cell71.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell72.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell73.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell74.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell75.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell76.setVerticalAlignment(Element.ALIGN_MIDDLE);
            // 边框颜色
            cell71.setBorderColor(lightGrey);
            cell72.setBorderColor(lightGrey);
            cell73.setBorderColor(lightGrey);
            cell74.setBorderColor(lightGrey);
            cell75.setBorderColor(lightGrey);
            cell76.setBorderColor(lightGrey);
            // 去掉左右边框
            cell71.disableBorderSide(8);
            cell72.disableBorderSide(4);
            cell72.disableBorderSide(8);
            cell73.disableBorderSide(4);
            cell73.disableBorderSide(8);
            cell74.disableBorderSide(4);
            cell74.disableBorderSide(8);
            cell75.disableBorderSide(4);
            cell75.disableBorderSide(8);
            cell76.disableBorderSide(4);
            table7.addCell(cell71);
            table7.addCell(cell72);
            table7.addCell(cell73);
            table7.addCell(cell74);
            table7.addCell(cell75);
            table7.addCell(cell76);
            document.add(table7);

            // table8
            PdfPTable table8 = new PdfPTable(6);
            int width8[] = { 20, 18, 13, 20, 14, 15 };
            table8.setWidths(width8);
            PdfPCell cell81 = new PdfPCell(new Paragraph("差旅报销", FontChinese12));
            PdfPCell cell82 = new PdfPCell(new Paragraph("2011-11-11", FontChinese12));
            PdfPCell cell83 = new PdfPCell(new Paragraph("XXX", FontChinese12));
            PdfPCell cell84 = new PdfPCell(new Paragraph("XXX", FontChinese12));
            PdfPCell cell85 = new PdfPCell(new Paragraph("XXX", FontChinese12));
            PdfPCell cell86 = new PdfPCell(new Paragraph("XXX", FontChinese12));
            // 表格高度
            cell81.setFixedHeight(25);
            cell82.setFixedHeight(25);
            cell83.setFixedHeight(25);
            cell84.setFixedHeight(25);
            cell85.setFixedHeight(25);
            cell86.setFixedHeight(25);
            // 水平居中
            cell81.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell82.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell83.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell84.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell85.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell86.setHorizontalAlignment(Element.ALIGN_CENTER);
            // 垂直居中
            cell81.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell82.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell83.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell84.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell85.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell86.setVerticalAlignment(Element.ALIGN_MIDDLE);
            // 边框颜色
            cell81.setBorderColor(lightGrey);
            cell82.setBorderColor(lightGrey);
            cell83.setBorderColor(lightGrey);
            cell84.setBorderColor(lightGrey);
            cell85.setBorderColor(lightGrey);
            cell86.setBorderColor(lightGrey);
            // 去掉左右边框
            cell81.disableBorderSide(8);
            cell82.disableBorderSide(4);
            cell82.disableBorderSide(8);
            cell83.disableBorderSide(4);
            cell83.disableBorderSide(8);
            cell84.disableBorderSide(4);
            cell84.disableBorderSide(8);
            cell85.disableBorderSide(4);
            cell85.disableBorderSide(8);
            cell86.disableBorderSide(4);
            table8.addCell(cell81);
            table8.addCell(cell82);
            table8.addCell(cell83);
            table8.addCell(cell84);
            table8.addCell(cell85);
            table8.addCell(cell86);
            document.add(table8);
            // 加入空行
            Paragraph blankRow5 = new Paragraph(18f, " ", FontChinese18);
            document.add(blankRow5);

            // table9
            PdfPTable table9 = new PdfPTable(3);
            int width9[] = { 30, 50, 20 };
            table9.setWidths(width9);
            PdfPCell cell91 = new PdfPCell(new Paragraph("", FontChinese12));
            PdfPCell cell92 = new PdfPCell(new Paragraph("收到的报销金额", FontChinese12));
            PdfPCell cell93 = new PdfPCell(new Paragraph("1000", FontChinese24));
            cell92.setHorizontalAlignment(Element.ALIGN_RIGHT);
            cell92.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell93.setHorizontalAlignment(Element.ALIGN_LEFT);
            cell93.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell91.setBorder(0);
            cell92.setBorder(0);
            cell93.setBorder(0);
            table9.addCell(cell91);
            table9.addCell(cell92);
            table9.addCell(cell93);
            document.add(table9);

            document.close();

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        BillPDF billPDF = new BillPDF();
        createBillPDF(billPDF);
    }
}

将图片等信息修改后可以直接运行。通过完全用java代码生成的这个案例可以更好的理解java对pdf的操作的一些属性和方法等。