PDF笔记(二):Itext 实际项目案例

来源:互联网 发布:什么是栅格数据 编辑:程序博客网 时间:2024/06/06 03:29

一、PDF打印的思路:

(一)、输出生成: PDFPractise.java

package pdf.practise;import java.io.FileOutputStream;import java.io.IOException;import com.itextpdf.text.BaseColor;import com.itextpdf.text.Chunk;import com.itextpdf.text.Document;import com.itextpdf.text.DocumentException;import com.itextpdf.text.Element;import com.itextpdf.text.Font;import com.itextpdf.text.Image;import com.itextpdf.text.PageSize;import com.itextpdf.text.Paragraph;import com.itextpdf.text.Phrase;import com.itextpdf.text.Rectangle;import com.itextpdf.text.pdf.BaseFont;import com.itextpdf.text.pdf.PdfPCell;import com.itextpdf.text.pdf.PdfPTable;import com.itextpdf.text.pdf.PdfWriter;/** *  * @Title: 单纯输出PDF报表 * @Description: * @Copyright: Copyright (c) 2014 * @Company: SinoSoft *  * @author: ShaoMin * @version: 1.0 * @CreateDate:Nov 5, 2014 */public class PDFPractise {    /**     * @author ShaoMin     * @param args     */    public static void main(String[] args) {        PDFPractise tPDFPractise = new PDFPractise();        try {            tPDFPractise.createPdfFile();            // tPDFPractise.createPDFFile();        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 创建PDF     *      * @author ShaoMin     * @throws Exception     */    public void createPdfFile() throws Exception {        Document doc = new Document();        FileOutputStream out = new FileOutputStream("temp/pdf/practisePdfFile.pdf");        PdfWriter.getInstance(doc, out);        doc.open();        BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);        Font titleFont = new Font(bfChinese, 16, Font.BOLD);// 标题        Font tableTitleFont = new Font(bfChinese, 12, Font.BOLD);// 表格标题        Font conyentFont = new Font(bfChinese, 12, Font.NORMAL);// 内容        Paragraph title = new Paragraph("受理材料收取凭证", titleFont);        title.setAlignment(Rectangle.ALIGN_CENTER);// 居中        doc.add(title);        StringBuffer strBuff = new StringBuffer();        strBuff.append("兹收到客户  " + "SAM-SHO");        strBuff.append("(先生/女士)提交的保单号为    " + "123456789009876");        strBuff.append("     的申请材料,共   " + " 2 " + "  张保单。");        Paragraph content = new Paragraph(strBuff.toString(), conyentFont);        content.setAlignment(Rectangle.ALIGN_JUSTIFIED);        content.setFirstLineIndent(15f);// 首行缩进        content.setSpacingBefore(30f);// 上留白        doc.add(content);        String cont2 = "申请保全项目    " + " CM-退保";        content = new Paragraph(cont2, conyentFont);        content.setAlignment(Rectangle.ALIGN_JUSTIFIED);        content.setFirstLineIndent(15f);// 首行缩进        content.setSpacingBefore(15f);// 上留白        doc.add(content);        String cont3 = "所提供材料明细如下:";        content = new Paragraph(cont3, conyentFont);        content.setAlignment(Rectangle.ALIGN_JUSTIFIED);        content.setFirstLineIndent(15f);// 首行缩进        content.setSpacingBefore(15f);// 上留白        content.setSpacingAfter(15f);// 下留白        doc.add(content);        // 表格的处理是难点,特别是表格的跨行跨列        // 可以使用跨行也可以使用表格嵌套        int tCol = 5;        PdfPTable table = new PdfPTable(tCol);        table.setHorizontalAlignment(Element.ALIGN_LEFT);        table.setTotalWidth(500f);        table.setWidths(new float[] { 0.4f, 0.25f, 0.25f, 0.25f, 0.25f });        table.setWidthPercentage(100);        table.setLockedWidth(true);        String strTableTitle = "申请材料名称";        Paragraph tableTitle = new Paragraph(strTableTitle, tableTitleFont);        PdfPCell cell = new PdfPCell(tableTitle);        cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 水平居中        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中        cell.setRowspan(2);// 跨2行        table.addCell(cell);        strTableTitle = "申请材料类型";        tableTitle = new Paragraph(strTableTitle, tableTitleFont);        cell = new PdfPCell(tableTitle);        cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 水平居中        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中        cell.setColspan(2);// 跨2列        table.addCell(cell);        strTableTitle = "收取页数/份数";        tableTitle = new Paragraph(strTableTitle, tableTitleFont);        cell = new PdfPCell(tableTitle);        cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 水平居中        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中        cell.setRowspan(2);// 跨2行        table.addCell(cell);        strTableTitle = "备注";        tableTitle = new Paragraph(strTableTitle, tableTitleFont);        cell = new PdfPCell(tableTitle);        cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 水平居中        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中        cell.setRowspan(2);// 跨2行        table.addCell(cell);        // 这边属于第二行的表格        // 思路上,这点很关键        strTableTitle = "原件";        tableTitle = new Paragraph(strTableTitle, tableTitleFont);        cell = new PdfPCell(tableTitle);        cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 水平居中        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中        table.addCell(cell);        strTableTitle = "复印件";        tableTitle = new Paragraph(strTableTitle, tableTitleFont);        cell = new PdfPCell(tableTitle);        cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 水平居中        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中        table.addCell(cell);        String[] arrTitle = { "保险合同", "保险合同收据或发票", "保单贷款申请书", "保全变更申请书", "被保险人变更清单", "健康及财务告知", "授权委托书", "投保人身份证件", "被保险人身份证件", "身故受益人身份证件", "受托人身份证件", "投保人账号", "被保险人/监护人账号 ", "生存证明", "关系证明 ",                "其他受理材料 " };        int tRow = arrTitle.length;        for (int i = 0; i < tRow; i++) {            for (int j = 0; j < tCol; j++) {                if (j == 0) {                    // 左侧标题                    strTableTitle = arrTitle[i];                    tableTitle = new Paragraph(strTableTitle, conyentFont);                    cell = new PdfPCell(tableTitle);                    cell.setHorizontalAlignment(Element.ALIGN_LEFT);// 水平居中                    cell.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中                    table.addCell(cell);                } else {                    strTableTitle = i + "--" + j;                    tableTitle = new Paragraph(strTableTitle, conyentFont);                    cell = new PdfPCell(tableTitle);                    cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 水平居中                    cell.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中                    table.addCell(cell);                }            }        }        table.setSpacingAfter(15f);// 下留白        doc.add(table);        // 所有的都要指定中文,不然显示不出来        // Phrase没有位置的操作,但是空格会被保留        // 也可以使用表格处理,隐藏边框即可        Phrase tPhrase = new Phrase("    申请人:                                     " + "                                         " + "                                         " + "保全试算金额:",                conyentFont);        Paragraph tParagraph = new Paragraph(tPhrase);        doc.add(tParagraph);        // 尾部表格处理        PdfPTable footTable = new PdfPTable(2);        footTable.setTotalWidth(760f);        footTable.setWidths(new float[] { 4.6f, 1f });        footTable.setHorizontalAlignment(Element.ALIGN_LEFT);        strTableTitle = "   申请日期:";        tableTitle = new Paragraph(strTableTitle, conyentFont);        cell = new PdfPCell(tableTitle);        cell.setHorizontalAlignment(Element.ALIGN_LEFT);// 水平居中        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中        cell.setBorderWidth(0);        footTable.addCell(cell);        strTableTitle = "受理人:";        tableTitle = new Paragraph(strTableTitle, conyentFont);        cell = new PdfPCell(tableTitle);        cell.setHorizontalAlignment(Element.ALIGN_LEFT);// 水平居中        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中        cell.setBorderWidth(0);        footTable.addCell(cell);        strTableTitle = "   申请人电话:";        tableTitle = new Paragraph(strTableTitle, conyentFont);        cell = new PdfPCell(tableTitle);        cell.setHorizontalAlignment(Element.ALIGN_LEFT);//        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中        cell.setBorderWidth(0);        footTable.addCell(cell);        strTableTitle = "受理日期:";        tableTitle = new Paragraph(strTableTitle, conyentFont);        cell = new PdfPCell(tableTitle);        cell.setHorizontalAlignment(Element.ALIGN_LEFT);//        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);// 垂直居中        cell.setBorderWidth(0);        footTable.addCell(cell);        doc.add(footTable);                tParagraph = new Paragraph();        Chunk tChunk = new Chunk("   说明:  ",conyentFont);        tParagraph.add(tChunk);                tChunk = new Chunk("                                                                               ",conyentFont);        tChunk.setUnderline(0.1f, -2f);        tParagraph.add(tChunk);        tChunk = new Chunk("                                                                           ",conyentFont);        tChunk.setUnderline(0.1f, -2f);        tParagraph.add(tChunk);        tChunk = new Chunk("                                                                        ",conyentFont);        tChunk.setUnderline(0.1f, -2f);        tParagraph.add(tChunk);                tParagraph.setLeading(30f);        tChunk = new Chunk("                                                                          ",conyentFont);        tChunk.setUnderline(0.1f, -2f);        tParagraph.add(tChunk);        tChunk = new Chunk("                                                                          ",conyentFont);        tChunk.setUnderline(0.1f, -2f);        tParagraph.add(tChunk);                doc.add(tParagraph);                doc.close();        System.out.println("结束.....");    }    /**     *      * @author ShaoMin     *      */    public void createPDFFile() {        Document document = new Document(PageSize.A4, 80, 79, 20, 45); // A4纸大小,//                                                                       // 左、右、上、下        try {            // 中文处理            BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);            Font FontChinese = new Font(bfChinese, 14, Font.COURIER); // 其他所有文字字体            Font BoldChinese = new Font(bfChinese, 14, Font.BOLD); // 粗体            Font titleChinese = new Font(bfChinese, 20, Font.BOLD); // 模板抬头的字体            Font moneyFontChinese = new Font(bfChinese, 8, Font.COURIER); // 币种和租金金额的小一号字体            Font subBoldFontChinese = new Font(bfChinese, 8, Font.BOLD); // 币种和租金金额的小一号字体            // 使用PDFWriter进行写文件操作            PdfWriter.getInstance(document, new FileOutputStream("temp/pdf/pdfFile.pdf"));            document.open(); // 打开文档            // ------------开始写数据-------------------            Paragraph title = new Paragraph("起租通知书", titleChinese);// 抬头            title.setAlignment(Element.ALIGN_CENTER); // 居中设置            title.setLeading(1f);// 设置行间距//设置上面空白宽度            document.add(title);            title = new Paragraph("致:XXX公司", BoldChinese);// 抬头            title.setSpacingBefore(25f);// 设置上面空白宽度            document.add(title);            title = new Paragraph("         贵我双方签署的编号为 XXX有关起租条件已满足,现将租赁合同项下相关租赁要素明示如下:", FontChinese);            title.setLeading(22f);// 设置行间距            document.add(title);            float[] widths = { 10f, 25f, 30f, 30f };// 设置表格的列宽和列数 默认是4列            PdfPTable table = new PdfPTable(widths);// 建立一个pdf表格            table.setSpacingBefore(20f);// 设置表格上面空白宽度            table.setTotalWidth(500);// 设置表格的宽度            table.setWidthPercentage(100);// 设置表格宽度为%100            // table.getDefaultCell().setBorder(0);//设置表格默认为无边框            String[] tempValue = { "1", "2011-07-07", "2222元", "233元", "2014-12-22", "3000元", "9999元" }; // 租金期次列表            int rowCount = 1; // 行计数器            PdfPCell cell = null;            // ---表头            cell = new PdfPCell(new Paragraph("期次", subBoldFontChinese));// 描述            cell.setFixedHeight(20);            cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 设置内容水平居中显示            cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 设置垂直居中            table.addCell(cell);            cell = new PdfPCell(new Paragraph("租金日", subBoldFontChinese));// 描述            cell.setFixedHeight(20);            cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 设置内容水平居中显示            cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 设置垂直居中            table.addCell(cell);            cell = new PdfPCell(new Paragraph("各期租金金额", subBoldFontChinese));// 描述            cell.setFixedHeight(20);            cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 设置内容水平居中显示            cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 设置垂直居中            table.addCell(cell);            cell = new PdfPCell(new Paragraph("各期租金后\n剩余租金", subBoldFontChinese));// 描述            cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 设置内容水平居中显示            cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 设置垂直居中            cell.setFixedHeight(20);            table.addCell(cell);            for (int j = 1; j < tempValue.length; j++) {                if (j % 2 == 1) { // 第一列 日期                    cell = new PdfPCell(new Paragraph(rowCount + "", moneyFontChinese));// 描述                    cell.setFixedHeight(20);                    cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 设置内容水平居中显示                    cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 设置垂直居中                    table.addCell(cell);                    rowCount++;                }                cell = new PdfPCell(new Paragraph(tempValue[j], moneyFontChinese));// 描述                cell.setFixedHeight(20);                cell.setHorizontalAlignment(Element.ALIGN_CENTER);// 设置内容水平居中显示                cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 设置垂直居中                table.addCell(cell);            }            document.add(table);            title = new Paragraph("                租金总额:XXX", FontChinese);            title.setLeading(22f);// 设置行间距            document.add(title);            title = new Paragraph("         特此通知!", FontChinese);            title.setLeading(22f);// 设置行间距            document.add(title);            // -------此处增加图片和日期,因为图片会遇到跨页的问题,图片跨页,图片下方的日期就会脱离图片下方会放到上一页。            // 所以必须用表格加以固定的技巧来实现            float[] widthes = { 50f };// 设置表格的列宽和列数            PdfPTable hiddenTable = new PdfPTable(widthes);// 建立一个pdf表格            hiddenTable.setSpacingBefore(11f); // 设置表格上空间            hiddenTable.setTotalWidth(500);// 设置表格的宽度            hiddenTable.setWidthPercentage(100);// 设置表格宽度为%100            hiddenTable.getDefaultCell().disableBorderSide(1);            hiddenTable.getDefaultCell().disableBorderSide(2);            hiddenTable.getDefaultCell().disableBorderSide(4);            hiddenTable.getDefaultCell().disableBorderSide(8);            Image upgif = Image.getInstance("source/imag/bage.png");            upgif.scalePercent(7.5f);// 设置缩放的百分比%7.5            upgif.setAlignment(Element.ALIGN_RIGHT);            cell = new PdfPCell(new Paragraph("", FontChinese));// 描述            cell.setHorizontalAlignment(Element.ALIGN_RIGHT);// 设置内容水平居中显示            cell.addElement(upgif);            cell.setPaddingTop(0f); // 设置内容靠上位置            cell.setPaddingBottom(0f);            cell.setPaddingRight(20f);            cell.setBorder(Rectangle.NO_BORDER);// 设置单元格无边框            hiddenTable.addCell(cell);            cell = new PdfPCell(new Paragraph("XX 年 XX 月 XX 日                    ", FontChinese));// 金额            cell.setHorizontalAlignment(Element.ALIGN_RIGHT);// 设置内容水平居中显示            cell.setPaddingTop(0f);            cell.setPaddingRight(20f);            cell.setBorder(Rectangle.NO_BORDER);            hiddenTable.addCell(cell);            document.add(hiddenTable);            System.out.println("拼装起租通知书结束...");            document.close();        } catch (DocumentException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }    /**     * 支持中文     *      * @return     */    public Font getChineseFont() {        BaseFont bfChinese;        Font fontChinese = null;        try {            bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);            // fontChinese = new Font(bfChinese, 12, Font.NORMAL);            fontChinese = new Font(bfChinese, 12, Font.NORMAL, BaseColor.BLUE);        } catch (DocumentException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        return fontChinese;    }}

(二)、使用模板 : PdfTempletePractise.java

package pdf.practise;import java.io.FileOutputStream;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import com.itextpdf.text.BaseColor;import com.itextpdf.text.DocumentException;import com.itextpdf.text.Element;import com.itextpdf.text.Font;import com.itextpdf.text.Paragraph;import com.itextpdf.text.pdf.AcroFields;import com.itextpdf.text.pdf.AcroFields.Item;import com.itextpdf.text.pdf.BaseFont;import com.itextpdf.text.pdf.PdfContentByte;import com.itextpdf.text.pdf.PdfPCell;import com.itextpdf.text.pdf.PdfPTable;import com.itextpdf.text.pdf.PdfReader;import com.itextpdf.text.pdf.PdfStamper;/** *  * @Title: 模板报表制作 * @Description: * @Copyright: Copyright (c) 2014 * @Company: SinoSoft *  * @author: ShaoMin * @version: 1.0 * @CreateDate:Nov 5, 2014 */public class PdfTempletePractise {    protected PdfStamper mPdfStamper = null;// pdf解析器    // 定义动态表的各类数据    private final int TABLE_COLNUM = 4;// 整个表格列数    private final float TABLE_WIDTH = 369.7f;// 整个表格宽度    private final float ROW_HEIGHT = 19.19f;// 单元格高度    private final float XPOS = 174.52f;// 整个表格 X坐标    private final float YPOS = 569.18f; // 整个表格 Y坐标    private final float[] ROW_WIDTHS = { 0.2565f, 0.25f, 0.25f, 0.245f };// 单元格宽度    /**     * @author ShaoMin     * @param args     */    public static void main(String[] args) {        PdfTempletePractise tPdfTemplete = new PdfTempletePractise();        Map<String, String> mMapDatas = new HashMap<String, String>();        mMapDatas.put("PdfResultFile", "temp/pdf/templetePdfFile.pdf");// 生成的文件路径        mMapDatas.put("PdfTemplateFile", "source/pdf/templete/EdorAcceptResource.pdf");// 获取模板路径        mMapDatas.put("CustomerName", "SAM-SHO");// 客户姓名        mMapDatas.put("ContNo", "123456789098765");// 合同号        mMapDatas.put("ContCount", "1");// 保单个数        mMapDatas.put("EdorType", "CT-退保");// 保全类型        mMapDatas.put("GetMoney", "999.99");// 保全失算金额        mMapDatas.put("AcceptName", "人寿保险");// 受理人        mMapDatas.put("AcceptDate", "2014-14-1");// 受理日期        tPdfTemplete.fillTempleteDates(mMapDatas);// 表单域数据        List<String[]> tableLists = new ArrayList<String[]>();        for (int i = 0; i < 16; i++) {            String[] arrStr = new String[4];            arrStr[0] = i + "--" + 0;            arrStr[1] = i + "--" + 1;            arrStr[2] = i + "--" + 2;            arrStr[3] = i + "--" + 3;            tableLists.add(arrStr);        }        tPdfTemplete.createTable(tableLists);                System.out.println("完成.........");    }    /**     * 填充模板数据,表单域数据     *      * @author ShaoMin     * @param map     */    @SuppressWarnings("unchecked")    protected boolean fillTempleteDates(Map<String, String> map) {        String tPdfResultFile = map.get("PdfResultFile");// 生成的文件路径        String tPdfTemplateFile = map.get("PdfTemplateFile");// 获取模板路径        FileOutputStream fos = null;        PdfReader reader = null;        try {            fos = new FileOutputStream(tPdfResultFile);// 需要生成PDF            reader = new PdfReader(tPdfTemplateFile);// 模板            mPdfStamper = new PdfStamper(reader, fos);// 解析            AcroFields form = mPdfStamper.getAcroFields();// 获取到模板上预定义的参数域            // 获取模板中定义的变量            Map<String, Item> acroFieldMap = form.getFields();            for (Map.Entry<String, Item> entry : acroFieldMap.entrySet()) {                // 获得块名                String fieldName = entry.getKey();                String fieldValue = map.get(fieldName);// 通过名字,获取传入的参数值                if (!"".equals(fieldValue)) {                    // 为模板中的变量赋值                    form.setField(fieldName, fieldValue);                    System.out.println(fieldName + "," + fieldValue);                }            }            // 模板中的变量赋值之后不能编辑            mPdfStamper.setFormFlattening(true);            reader.close();// 阅读器关闭,解析器暂时不关闭,因为创建动态表格还需要使用        } catch (Exception e) {            e.printStackTrace();            return false;        } finally {            if (reader != null) {                reader.close();            }        }        return true;    }    /**     * 创建表格     *      * @author ShaoMin     * @param resultList     * @return     */    protected boolean createTable(List<String[]> resultList) {        PdfPTable table = new PdfPTable(TABLE_COLNUM);// 创建表格        PdfPCell cell = null;        try {            for (String[] tResults : resultList) {                for (int i = 0; i < tResults.length; i++) {                    // 创建单元格,并置上值                    Paragraph para = new Paragraph(tResults[i], getChineseFont());                    para.setAlignment(Element.ALIGN_CENTER);                    cell = new PdfPCell(para);                    // cell.setBorderWidth(0)//边框                    cell.setFixedHeight(ROW_HEIGHT);// 单元格高度                    cell.setHorizontalAlignment(Element.ALIGN_CENTER);//水平位置                    cell.setVerticalAlignment(Element.ALIGN_MIDDLE);//垂直位置                    table.addCell(cell);// 单元格加入动态表格                }            }            table.setWidths(ROW_WIDTHS);// 设置每个单元格的宽度,是比例关系            table.setTotalWidth(TABLE_WIDTH);// 总宽度            PdfContentByte tContent = mPdfStamper.getOverContent(1);// 获取模板的层次            table.writeSelectedRows(0, -1, 0, -1, XPOS, YPOS, tContent);// 把表格写入模板的固定位置(0行-最后一行| 0列-最后一列)            mPdfStamper.close();// 关闭解析器        } catch (DocumentException e) {            e.printStackTrace();            return false;        } catch (IOException e) {            e.printStackTrace();            return false;        } finally {            try {                if (mPdfStamper != null) {                    mPdfStamper.close();// 关闭解析器                }            } catch (DocumentException e) {                e.printStackTrace();            } catch (IOException e) {                e.printStackTrace();            }        }        return true;    }    /**     * 支持中文     *      * @return     */    public Font getChineseFont() {        BaseFont bfChinese;        Font fontChinese = null;        try {            bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);            // fontChinese = new Font(bfChinese, 12, Font.NORMAL);            fontChinese = new Font(bfChinese, 12, Font.NORMAL, BaseColor.BLUE);        } catch (DocumentException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        return fontChinese;    }}

二、PDF打印设计:

1、核心:

1)模板方法设计模式:Template Method设计

2)抽象类的使用

2、实现

1)打印抽象类:AbstractPDFPrintBL.java

2)实例,受理凭证打印: EdorAcceptPDFPrintBL.java

3)实际使用的过程中需要传递List和map容器的数据。表格数据放入List,其他数据放入Map。

3、代码如下:

1)抽象类如下:

package com.sinosoft.lis.agentprint;import java.io.File;/** * @Title: PDF打印公共类 * @Description:其他PDF打印类,都可以继承本类,例如受理凭证打印类:EdorAcceptPDFPrintBL * @Copyright: Copyright (c) 2014 * @Company:  *  * @author: ShaoMin * @version: 1.0 * @CreateDate:Oct 27, 2014 */public abstract class AbstractPDFPrintBL {    protected Logger logger = Logger.getLogger(getClass());    protected CErrors mErrors = new CErrors();    /** 存放动态表格的数据 */    protected List<String[]> lists = new ArrayList<String[]>();    /** 用于存放要填充的模板数据 */    protected Map<String, String> map = new HashMap<String, String>();    protected PdfStamper mPdfStamper = null;// pdf解析器    /**     * 传输数据的公共方法     */    public boolean submitData() {        // 获取数据        if (!getInput()) {            return false;        }        // 数据校验        if (!checkDatas()) {            return false;        }        // 打印处理        if (!dealData()) {            return false;        }        return true;    }    /**     * 获取必要的数据     *      * @author ShaoMin     * @return     */    protected abstract boolean getInput();    /**     * 数据校验     *      * @author ShaoMin     * @return     */    protected abstract boolean checkDatas();    /**     * 业务处理     *      * @author ShaoMin     * @return     */    private boolean dealData() {        // 删除临时文件        this.deleteTempFile();        // 填充模板数据        if (!fillTempleteDates(map)) {            try {                if (mPdfStamper != null) {                    mPdfStamper.close();                }            } catch (DocumentException e) {                e.printStackTrace();            } catch (IOException e) {                e.printStackTrace();            }            return false;        }        // 写入动态数据创建表格        if (lists != null && !lists.isEmpty()) {            if (!createTable(lists)) {                return false;            }        }                // 不使用模板,直接输出PDF        if(!createPdfFile()){            return false;        }        return true;    }    /**     * 不使用模板,直接输出PDF(可以输出文本和表格)     * @author ShaoMin     * @return     */    protected  boolean createPdfFile() {        return true;    }    /**     * 生成pdf的动态表格,子类可以重写实现复杂逻辑     * 没有表格输出,在构造函数时,传入空的集合即可。     * 如Collections.EMPTY_LIST,不建议直接传null     * @author ShaoMin     * @param resultList     * @return     * @throws Exception     */    protected abstract boolean createTable(List<String[]> resultList);        /**     * 支持汉字     */    protected BaseFont getBaseFont() {        BaseFont tBaseFont = null;        try {            tBaseFont = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);        } catch (Exception e) {            e.printStackTrace();            return null;        }        return tBaseFont;    }    /**     * 删除临时文件     * @author ShaoMin     * @param filePath     * @return     */    private boolean deleteTempFile() {        String tPdfResultFile = map.get("PdfResultFile");        File tFile = new File(tPdfResultFile);        if (tFile.exists() && tFile.isFile()) {            tFile.delete();        }        return true;    }    /**     * 填充模板数据,子类可以重写实现复杂逻辑     * @author ShaoMin     * @param map     */    @SuppressWarnings("unchecked")    protected boolean fillTempleteDates(Map<String, String> map) {        String tPdfResultFile = map.get("PdfResultFile");// 生成的文件路径        String tPdfTemplateFile = map.get("PdfTemplateFile");// 获取模板路径        FileOutputStream fos = null;        PdfReader reader = null;        try {            fos = new FileOutputStream(tPdfResultFile);// 需要生成PDF            reader = new PdfReader(tPdfTemplateFile);// 模板            mPdfStamper = new PdfStamper(reader, fos);// 解析            AcroFields form = mPdfStamper.getAcroFields();// 获取到模板上预定义的参数域            // 获取模板中定义的变量            Map<String, Item> acroFieldMap = form.getFields();            for (Map.Entry<String, Item> entry : acroFieldMap.entrySet()) {                // 获得块名                String fieldName = entry.getKey();                String fieldValue = map.get(fieldName);// 通过名字,获取传入的参数值                if (!"".equals(fieldValue)) {                    // 为模板中的变量赋值                    form.setField(fieldName, fieldValue);                    System.out.println(fieldName + "," + fieldValue);                }            }            // 模板中的变量赋值之后不能编辑            mPdfStamper.setFormFlattening(true);            reader.close();// 阅读器关闭,解析器暂时不关闭,因为创建动态表格还需要使用        } catch (Exception e) {            e.printStackTrace();            return false;        } finally {            if (reader != null) {                reader.close();            }        }        return true;    }    /**     * 判断字符串是否为空     * @param str 字符串     * @return boolean     */    protected boolean isEmpty(String str) {        if (str == null || "".equals(str)) {            return true;        }        return false;    }    /**     * 判断字符串不为空     * @param str 字符串     * @return boolean     */    protected boolean isNotEmpty(String str) {        return !isEmpty(str);    }    public void setLists(ArrayList<String[]> lists) {        this.lists = lists;    }    public void setMap(Map<String, String> map) {        this.map = map;    }}



2)实现类如下:打印凭证
package com.sinosoft.lis.agentprint;import java.io.IOException;/** *  * @Title: 受理凭证打印类 * @Description: * @Copyright: Copyright (c) 2014 * @Company:  *  * @author: SAM * @version: 1.0 * @CreateDate:2014-5-27 */public class EdorAcceptPDFPrintBL extends AbstractPDFPrintBL {    // 定义动态表的各类数据    private final int TABLE_COLNUM = 4;// 整个表格列数    private final float TABLE_WIDTH = 369.7f;// 整个表格宽度    private final float ROW_HEIGHT = 19.19f;// 单元格高度    private final float XPOS = 174.52f;// 整个表格 X坐标    private final float YPOS = 569.18f; // 整个表格 Y坐标//    private final int TABLE_BORDER = 120;// 表格的边框    private final float FONT_SIZE = 8f;// 字体的大小    private final float[] ROW_WIDTHS = {0.2565f, 0.25f, 0.25f, 0.245f};//单元格宽度        // 私有构造方法    private EdorAcceptPDFPrintBL() {    }    private EdorAcceptPDFPrintBL(Map<String, String> map, List<String[]> lists) {        this.map = map;        this.lists = lists;    }        public static EdorAcceptPDFPrintBL getIntance() {        return new EdorAcceptPDFPrintBL();    }        /**     * 私有静态工厂方法,取代构造方法使用     * 如不需要动态表格的打印,这边lists参数可以传入空的集合     * 如Collections.EMPTY_LIST,不建议直接传null     * @author ShaoMin     * @param map     * @param lists     * @return     */    public static EdorAcceptPDFPrintBL getIntanceByColection(Map<String, String> map, List<String[]> lists) {        return new EdorAcceptPDFPrintBL(map, lists);    }    @Override    public boolean checkDatas() {        if (map == null || map.isEmpty()) {            mErrors.addOneError("数据传输失败");            return false;        }        if (lists == null || lists.isEmpty()) {            mErrors.addOneError("数据传输失败");            return false;        }        return true;    }    @Override    protected boolean getInput() {        return true;    }    @Override    protected boolean createTable(List<String[]> resultList) {        PdfContentByte tContent = mPdfStamper.getOverContent(1);//获取模板的层次        PdfPTable table = new PdfPTable(TABLE_COLNUM);        PdfPCell cell = null;        try {                        //设置中文字体            BaseFont bfChinese = this.getBaseFont();            Font subBoldFontChinese = new Font(bfChinese, FONT_SIZE, Font.NORMAL);            for (String[] tResults : resultList) {                for (int i = 0; i < tResults.length; i++) {                    //创建单元格,并置上值                    Paragraph para = new Paragraph(tResults[i], subBoldFontChinese);                    para.setAlignment(Element.ALIGN_CENTER);                    cell = new PdfPCell(para);                    // cell.setBorder(TABLE_BORDER);//边框                    cell.setFixedHeight(ROW_HEIGHT);// 单元格高度                    cell.setHorizontalAlignment(Element.ALIGN_CENTER);                    cell.setVerticalAlignment(Element.ALIGN_MIDDLE);                    table.addCell(cell);//单元格加入动态表格                }            }            table.setWidths(ROW_WIDTHS);// 设置每个单元格的宽度            table.setTotalWidth(TABLE_WIDTH);// 总宽度            table.writeSelectedRows(0, -1, 0, -1, XPOS, YPOS, tContent);//把表格写入模板的固定位置            mPdfStamper.close();//关闭解析器        } catch (DocumentException e) {            e.printStackTrace();            return false;        } catch (IOException e) {            e.printStackTrace();            return false;        } finally {            try {                if (mPdfStamper != null) {                    mPdfStamper.close();//关闭解析器                }            } catch (DocumentException e) {                e.printStackTrace();            } catch (IOException e) {                e.printStackTrace();            }        }        return true;    }    }


3)调用代码如下:

// 1- 定义必要容器mMapDatas = new HashMap<String, String>();mListDatas = new ArrayList<String[]>();// 2-封装map数据// 2-1 获取必要信息:如文件名称、保全类型名等,并封装map数据mMapDatas.put("PdfTemplateFile", "templte.pdf");// PDF模版文件mMapDatas.put("PdfResultFile", "result.psd");// 生成PDF文件mMapDatas.put("PdfTempPath", "tem/pdf");// 生成PDF临时路径mMapDatas.put("CustomerName", “Sam-SHO”);// 客户姓名mMapDatas.put("ContNo", "123456789");// 合同号mMapDatas.put("ContCount", "1");// 保单个数mMapDatas.put("EdorType", "CT-退保");// 保全类型mMapDatas.put("GetMoney", "200"));// 保全失算金额mMapDatas.put("AcceptName", "SAM");// 受理人mMapDatas.put("AcceptDate", "2014-11-07");// 受理日期// 3-封装list数据// 3-1 获取受理资料信息-// 3-2 封装list数据for (int i = 1; i <= B.size(); i++) {    A a = B.get(i);    String[] strArr = new String[4];// 4列数据    String tCopyFlag = a.getResourceCopyFlag();    // 0-原件;1-复印件;2-无    strArr[0] = "0".equals(tCopyFlag) ? "Y" : "";// 原件    strArr[1] = "1".equals(tCopyFlag) ? "Y" : "";// 复印件    strArr[2] = a.getResourcePages();// 份数    strArr[3] = a.getResourceDesc();// 备注    mListDatas.add(strArr);}// 4-调用打印类EdorAcceptPDFPrintBL tPdfPrint = EdorAcceptPDFPrintBL.getIntanceByColection(mMapDatas, mListDatas);if (!tPdfPrint.submitData()) {return false;}

0 0