IText5.5来动态生成PDF文件

背景:前段时候公司要开发合同PDF,公司可以根据该PDF打印出一份合同。合同中有些地方需要动态生成,因此并不能完全使用Pdf模板的形式来进行开发,比如某个PDF页面需要动态生成表格,那个这个页面就不能使用pdf模板来进行开发。但是合同中大部分都是固定不变的,所以可以将固定分离出来,只用专心开发动态部分,最后再将这些PDF合并成一个PDF就行了。

知识点:

1. 使用Itext5.5动态生成表格

2. PDF合并

3.设置页面大小:查看Itext的源码可以发现 PageSize.A4 = new Rectangle(595.0F, 842.0F);//像素

工程的目录结构如下:

GenerateContactPDFUtil.java 中的代码如下:

package com.utils;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.Font;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.vo.PolicyPlan;

/**
 * 
 *生成 合同Pdf
 */
public class GenerateContactPDFUtil {
    public static void main(String[] args) throws Exception{
    	String fullPath = "table.pdf";
    	//合同基本信息
    	Map<String, String> contactInfo = new HashMap<String, String>();
    	contactInfo.put("firstParty", "高雄");
    	contactInfo.put("secondParty", "北京");
    	contactInfo.put("peopleCount", "100");
    	contactInfo.put("year", "2015");
    	contactInfo.put("month", "8");
    	contactInfo.put("day", "22");
   
    	//表头
    	String[] policyPlans = {"险种","保险责任","保险费"};
    	//数据
    	List<PolicyPlan> policyPlanList = new ArrayList<PolicyPlan>();
    	PolicyPlan policyPlan1 = new PolicyPlan("CAG13","意外身故", "455"); //实体类
    	PolicyPlan policyPlan2 = new PolicyPlan("CAG14","民用或商用航班飞机意外伤残", "455");
    	PolicyPlan policyPlan3 = new PolicyPlan("CAG15","营运水上交通工具意外伤残", "455");
    	PolicyPlan policyPlan4 = new PolicyPlan("CAG15","营运水上交通工具意外身故", "455");
    	PolicyPlan policyPlan5 = new PolicyPlan("CAG16","出行无忧", "1000");
        policyPlanList.add(policyPlan1);
        policyPlanList.add(policyPlan2);
        policyPlanList.add(policyPlan3);
        policyPlanList.add(policyPlan4);
        policyPlanList.add(policyPlan5);
        createContactPdfHead(fullPath, contactInfo, policyPlans, policyPlanList);
 
    }
    	
    /**
     * tableHead 表头数据
     * tableDataList 表中数据
     * return PDF名字
     */
    public static void createContactPdfHead(String fullPath, Map<String, String> contactInfo, String[] tableHeads, List<PolicyPlan> tableDataList) throws Exception{
    	//Document doc = new Document(PageSize.B5);
        Document document = new Document(PageSize.A4, 80, 80, 90, 25); //设置成A4纸大小,内容距左右上下的距离
        try {
        	PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(fullPath));
            document.open();//打开PDF文件进行编辑
            // 插入一个段落
            //设置中文字体
            BaseFont baseFontChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            //1.标题字体
            Font headFont =  new  Font(baseFontChinese , 16 , Font.BOLD);
            Font headFontTitle =  new  Font(baseFontChinese , 14 , Font.BOLD);
            //2.正文字体
            Font contentFontFirst =  new  Font(baseFontChinese , 12 , Font.NORMAL);
            Font contentFontSecond =  new  Font(baseFontChinese , 10 , Font.NORMAL);
            
            //设置标题
            Paragraph head1 = new Paragraph("通过Email方式提交保全申请的授权协议", headFont);
            head1.setAlignment(1);//设置段落居中
            head1.setSpacingAfter(50);  
            document.add(head1);
            
            //甲方
            Chunk theFirstParty = new Chunk("甲方: ", headFontTitle);
            Chunk theFirstPartyName = new Chunk(contactInfo.get("firstParty") , headFontTitle);
            theFirstPartyName.setTextRise(1);
            //第一个参数:下划线粗细, 第二个参数:下划线Y轴位置
            theFirstPartyName.setUnderline(0.5f, -3f);
            Phrase party = new Phrase();
            party.add(theFirstParty);
            party.add(theFirstPartyName);
            Paragraph head2 = new Paragraph(party);
            head2.setSpacingAfter(30);
            document.add(head2);
            
            //乙方
            Chunk theSecondParty = new Chunk("乙方: 海康人寿保险有限公司 ", headFontTitle);
            Chunk theSecondPartyName1 = new Chunk(contactInfo.get("secondParty") , headFontTitle);
            theSecondPartyName1.setTextRise(1);
            //第一个参数:下划线粗细, 第二个参数:下划线Y轴位置
            theSecondPartyName1.setUnderline(0.5f, -3f);
            Chunk theSecondPartyName2 = new Chunk("分公司" , headFontTitle);
            Phrase secondParty = new Phrase();
            secondParty.add(theSecondParty);
            secondParty.add(theSecondPartyName1);
            secondParty.add(theSecondPartyName2);
            Paragraph head3 = new Paragraph(secondParty);
            head3.setSpacingAfter(30);
            document.add(head3);
            
            //甲方在某某保险有限公司          分公司为      名员工投保了团体人寿保险,生效日期      年    月   日。
            Chunk contentParty1 = new Chunk("       甲方在某某保险有限公司 ", contentFontFirst);
            Chunk contentParty2 = new Chunk(contactInfo.get("secondParty"), contentFontFirst);
            contentParty2.setTextRise(1);
            //第一个参数:下划线粗细, 第二个参数:下划线Y轴位置
            contentParty2.setUnderline(0.5f, -3f);
            Chunk contentParty3 = new Chunk("分公司为 ", contentFontFirst);
//            String companyPersonCountStr = "100";//100个人
            Chunk contentParty4 = new Chunk(contactInfo.get("peopleCount"), contentFontFirst);
            contentParty4.setTextRise(1);
            //第一个参数:下划线粗细, 第二个参数:下划线Y轴位置
            contentParty4.setUnderline(0.5f, -3f);
            Chunk contentParty5 = new Chunk("名员工投保了团体人寿保险," , contentFontFirst);
 
            //生效日期      年    月   日。
            Chunk effectiveDate = new Chunk("生效日期 ", contentFontFirst);
//            String yearStr = "2014";
            Chunk yearParty = new Chunk(contactInfo.get("year"), contentFontFirst);
            yearParty.setTextRise(1);
            //第一个参数:下划线粗细, 第二个参数:下划线Y轴位置
            yearParty.setUnderline(0.5f, -3f);
            Chunk yearPartyName = new Chunk("年 ", contentFontFirst);
//            String monthStr = "12";
            Chunk monthParty = new Chunk(contactInfo.get("month"), contentFontFirst);
            monthParty.setTextRise(1);
            //第一个参数:下划线粗细, 第二个参数:下划线Y轴位置
            monthParty.setUnderline(0.5f, -3f);
            Chunk monthPartyName = new Chunk("月 ", contentFontFirst);
//            String dayStr = "12";
            Chunk dayParty = new Chunk(contactInfo.get("day"), contentFontFirst);
            dayParty.setTextRise(1);
            //第一个参数:下划线粗细, 第二个参数:下划线Y轴位置
            dayParty.setUnderline(0.5f, -3f);
            Chunk dayPartyName = new Chunk("日 ", contentFontFirst);

            Phrase contentPhrase = new Phrase();
            contentPhrase.add(contentParty1);
            contentPhrase.add(contentParty2);
            contentPhrase.add(contentParty3);
            contentPhrase.add(contentParty4);
            contentPhrase.add(contentParty5);
            contentPhrase.add(effectiveDate);
            contentPhrase.add(yearParty);
            contentPhrase.add(yearPartyName);
            contentPhrase.add(monthParty);
            contentPhrase.add(monthPartyName);
            contentPhrase.add(dayParty);
            contentPhrase.add(dayPartyName);
            Paragraph head4 = new Paragraph(contentPhrase);
            head4.setSpacingAfter(10);
            document.add(head4);
            
            //保险方案:
            Paragraph insuredPlanParagraph = new Paragraph("保险方案:",contentFontFirst);
            insuredPlanParagraph.setIndentationLeft(20);//设置左侧缩进E
            insuredPlanParagraph.setSpacingAfter(10);
            document.add(insuredPlanParagraph);
            PdfPTable policyPlanTable = new PdfPTable(tableHeads.length); //设置表格有多少列
            int width[] = {20,60,20};//设置每列宽度比例   
            policyPlanTable.setWidths(width); 
            policyPlanTable.setWidthPercentage(100);//占页面宽度比例 
            //设置表格中单元格的属性,所有单元格都可以使用
            PdfPCell pdfPCell = new PdfPCell();//创建一个单元格
	       	//设置字体水平居中
            pdfPCell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);//设置水平对齐
	       	//设置字体垂直对齐居中
            pdfPCell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
            //保险方案内容:
            for(String head : tableHeads){
            	 pdfPCell.setPhrase(new Phrase(head , contentFontFirst));
            	 policyPlanTable.addCell(pdfPCell);
            }
            policyPlanTable.completeRow();
            for(PolicyPlan policyPlan : tableDataList){
	           	pdfPCell.setPhrase(new Phrase(policyPlan.getRiskCode(), contentFontFirst));
	           	policyPlanTable.addCell(pdfPCell);
	           	pdfPCell.setPhrase(new Phrase(policyPlan.getLiability(), contentFontFirst));
	           	policyPlanTable.addCell(pdfPCell);
	           	pdfPCell.setPhrase(new Phrase(policyPlan.getFee(), contentFontFirst));
	           	policyPlanTable.addCell(pdfPCell);
	           	policyPlanTable.completeRow();//完成行
	           
            }  
            document.add(policyPlanTable);
            
            //团体告知:
            Paragraph groupInformingParagraph = new Paragraph("团体告知:",contentFontFirst);
            groupInformingParagraph.setIndentationLeft(20);//设置左侧缩进E
            groupInformingParagraph.setSpacingBefore(20);
            groupInformingParagraph.setSpacingAfter(10);
            document.add(groupInformingParagraph);
            //团体告知内容:
            //1.设置表格属性
            PdfPTable groupInformingTable = new PdfPTable(2);
            int groupInfowidth[] = {85,15};//设置每列宽度比例   
            groupInformingTable.setWidths(groupInfowidth); 
            groupInformingTable.setWidthPercentage(100);//占页面宽度比例   
            //1.设置单元格样式
            //1.1informingInfo style
            PdfPCell informingInfoPdfPCell = new PdfPCell();//创建一个单元格
	       	//设置字体水平居中
            informingInfoPdfPCell.setHorizontalAlignment(PdfPCell.LEFT);//设置左对齐
	       	//设置字体垂直对齐居中
            informingInfoPdfPCell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
            //1.2 select style
            PdfPCell checkBoxPdfPCell = new PdfPCell();//创建一个单元格
	       	//设置字体水平居中
            checkBoxPdfPCell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);//设置水平对齐
	       	//设置字体垂直对齐居中
            checkBoxPdfPCell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
            
            //1.第一条
            informingInfoPdfPCell.setPhrase(new  Phrase("1、	目前是否有正在病假中(产假除外),且不在岗时间达到或超过10个工作日的人员?", contentFontSecond));
            groupInformingTable.addCell(informingInfoPdfPCell);
            checkBoxPdfPCell.setPhrase(new  Phrase("囗是       囗否" , contentFontSecond));
            groupInformingTable.addCell(checkBoxPdfPCell);
            groupInformingTable.completeRow();
            //2.第二条
            informingInfoPdfPCell.setPhrase(new  Phrase("2、	目前是否有需要长期(一年累计超过30天)接受住院治疗的人员?", contentFontSecond));
            groupInformingTable.addCell(informingInfoPdfPCell);
            checkBoxPdfPCell.setPhrase(new  Phrase("囗是       囗否" , contentFontSecond));
            groupInformingTable.addCell(checkBoxPdfPCell);
            groupInformingTable.completeRow();
            
            //3.第三条
            informingInfoPdfPCell.setPhrase(new  Phrase("3、   近期1年内是否有因患疾病而不能全勤或全量工作,实际工作时长或工作量低于正常1/2的人员?", contentFontSecond));
            groupInformingTable.addCell(informingInfoPdfPCell);
            checkBoxPdfPCell.setPhrase(new  Phrase("囗是       囗否" , contentFontSecond));
            groupInformingTable.addCell(checkBoxPdfPCell);
            groupInformingTable.completeRow();
            
            //第4条
            informingInfoPdfPCell.setPhrase(new  Phrase("4、  目前或过去是否有以下情况被保险人人员? \n (1)曾接受器官移植手术或造血干细胞移植手术、主动脉手术、冠状动脉搭桥术或冠状动脉支架植入术;\n (2)腕关节或踝关节近躯干端以上完全缺失、深度昏迷状态、双耳失聪或双目失明、严重Ⅲ度烧伤、智力或神经障碍、语言能力丧失。", contentFontSecond));
            groupInformingTable.addCell(informingInfoPdfPCell);
            checkBoxPdfPCell.setPhrase(new  Phrase("囗是       囗否" , contentFontSecond));
            groupInformingTable.addCell(checkBoxPdfPCell);
            groupInformingTable.completeRow();
            
            //第五条
            informingInfoPdfPCell.setPhrase(new  Phrase("5、  有无员工的职业涉及或接触任何危险物(化学物质、爆炸物、有毒物质或其他危险物)、高空作业、潜水或水下作业、隧道坑道或井下作业等危险工作?", contentFontSecond));
            groupInformingTable.addCell(informingInfoPdfPCell);
            checkBoxPdfPCell.setPhrase(new  Phrase("囗是       囗否" , contentFontSecond));
            groupInformingTable.addCell(checkBoxPdfPCell);
            groupInformingTable.completeRow();
            
            document.add(groupInformingTable);
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            document.close();
        }
    }
}

生成的PDF见附件。。。。

问题:

1.在使用itext5.5 时 中文不显示。

解决:在使用Itext5.5时,就不能使用老版本itext-asian.jar包了,应该使用更新版本的itext-asian.jar。细心的你可以发现老板的itext-asian与新版本的itext-asian的结构不一样。附件中提供了与itext5.5匹配的itext-asian供大家下载。

猜你喜欢

转载自weigang-gao.iteye.com/blog/2222654