itext 生成pdf、pdf模板生成pdf

itext生成PDF、PDF模板生成PDF

一、itxet生成PDF五个步骤

第 1 步:创建一个 PdfWriter 对象
 该PdfWriter类表示PDF文档的作家。此类属于包com.itextpdf.kernel.pdf。此类的构造函数接受一个字符串,表示要在其中创建 PDF 的文件的路径。
通过向其构造函数传递一个字符串值(表示您需要创建 PDF 的路径)来实例化 PdfWriter 类,如下所示。

第 2 步:创建一个 PdfDocument 对象
 该PdfDocument类为表示在iText的PDF文档类。此类属于包com.itextpdf.kernel.pdf。要实例化此类(在写入模式下),您需要将PdfWriter类的对象传递给其构造函数。
通过将上面创建的 PdfWriter 对象传递给其构造函数来实例化 PdfDocument 类,如下所示。

第 3 步:添加一个空页面
 PdfDocument类的addNewPage()方法用于在 PDF 文档中创建一个空白页面。
为上一步创建的 PDF 文档添加一个空白页面,如下所示。

第 4 步:创建一个 Document 对象
 包com.itextpdf.layout的Document类是创建自给自足的 PDF 时的根元素。此类的构造函数之一接受类 PdfDocument 的对象。
通过传递在前面的步骤中创建的类PdfDocument的对象来实例化Document类,如下所示。

步骤 5:关闭文档
 使用Document类的close()方法关闭文档,如下所示。

二、itext生成pdf

1.代码

 1.1.依赖

<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
<dependency>
	<groupId>com.itextpdf</groupId>
	<artifactId>itextpdf</artifactId>
	<version>5.5.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.itextpdf/itext-asian -->
<!--字体集-->
<dependency>
	<groupId>com.itextpdf</groupId>
	<artifactId>itext-asian</artifactId>
	<version>5.2.0</version>
</dependency>

 1.2基本使用

代码如下

/**
     *
     * @param value 文本
     * @param font 字体
     * @param horizontalAlignment 水平样式 0-left, 1-center, 2-right
     * @param verticalAlignment 垂直样式  4-top, 5-middle, 6-bottom;
     * @param colspan 列合并
     * @param rowspan 行合并
     * @param borderSide 外边框
     *  0-默认
     *  1-隐藏上边框
     *  2-隐藏下边框
     *  3-隐藏上、下边框
     *  4-隐藏左边框
     *  5-隐藏左、上边框
     *  6-隐藏左、下边框
     *  7-隐藏左、上、下边框
     *  8-隐藏右边框
     *  9-隐藏右、上边框
     *  10-隐藏右、下边框
     *  11-隐藏右、上、下边框
     *  12-隐藏左、右边框
     *  13-隐藏上、左、右边框
     *  14-隐藏下、左、右边框
     *  15-隐藏全部
     * @return
     */
public static PdfPCell createCell(String value, Font font, int horizontalAlignment, int verticalAlignment, int colspan, int rowspan, int borderSide) {
	PdfPCell cell = new PdfPCell();
	cell.setPhrase(new Phrase(value, font));//存值
	cell.setHorizontalAlignment(horizontalAlignment);//水平居中
	if(verticalAlignment>0){
		cell.setUseAscender(true);//垂直居中
	}
	cell.setVerticalAlignment(verticalAlignment);//垂直居中
	if(colspan>0 ){
		cell.setColspan(colspan);
	}
	if(rowspan>0){
		cell.setRowspan(rowspan);
	}
	if(borderSide>0){
		cell.disableBorderSide(borderSide);
	}
	return cell;
}

public static void generatePDFDoc(){
	Document doc = new Document(PageSize.A4);//定义doc
	try {
		File file = new File("C:\\Users\\cbh17\\Desktop\\test.pdf");//生成目标文件
		file.createNewFile();
		PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream(file));
		writer.setPageEvent(new Watermark("LeaSoft"));// 水印
		
		doc.open();//open
		BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
		//2. BaseFont.createFont("C:/WINDOWS/Fonts/simsun.ttc", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
		//3. BaseFont.createFont("/simsun.ttc", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED); 
		Font font = new Font(bf, 10, Font.NORMAL, BaseColor.BLACK);//字体
		//使用中文字体有三种方式
		//1.使用itext自带的字体集包
		//2.使用本地的 字体资源
		//  2.1 windows下,字体资源在目录 C:/WINDOWS/Fonts,注意 ttc后缀要 加 ',1'
		//  2.2 linux 未尝试,不过同理,找到字体资源的绝对路径即可
		//3.可以将 字体资源 放到项目 当中
		Paragraph paragraph1 = new Paragraph("XXXXXXXXX", font);//段落
	    paragraph1.setAlignment(PdfPCell.ALIGN_CENTER);
	   	paragraph1.setLeading(14f); //行间距
		//paragraph1.setIndentationLeft(12); //设置左缩进
		//paragraph1.setIndentationRight(12); //设置右缩进
		//paragraph1.setFirstLineIndent(24); //设置首行缩进
		//paragraph1.setSpacingBefore(5f); //设置段落上空白
		//paragraph1.setSpacingAfter(10f); //设置段落下空白
	
		//itext中没有行和列的概念,只有单元格,因此在声明table时就要指定列数
		//然后按table.addCell(cell)顺序添加
		PdfPTable table = new PdfPTable(new float[] { 1f, 1.5f, 1f, 1.5f});
		//表头
		table.addCell(createCell("XXX", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE, 0,0,15));
		table.addCell(createCell("XXX", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE,3,0,15));
		table.addCell(createCell("XXX", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE,0,0,15));
		table.addCell(createCell("XXX", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE,0,0,15));
		table.addCell(createCell("XXX", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE,0,0,15));
		table.addCell(createCell("XXX", font, PdfPCell.ALIGN_LEFT, PdfPCell.ALIGN_MIDDLE,0,0,15));
		//动态表格
		for(int i = 0; i<6; i++){
			table.addCell(createCell("v", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
			table.addCell(createCell("v", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
			table.addCell(createCell("v", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
			table.addCell(createCell("v", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
			table.addCell(createCell("v", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
			table.addCell(createCell("v", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
			table.addCell(createCell("v", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
			table.addCell(createCell("v", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
		}
		doc.add(paragraph1);
        doc.add(table1);
	}catch (Exception e){
		e.printStackTrace();
	}finally {
		// 5.关闭文档
		if(doc!=null){
			doc.close();
		}
	}
}

二、pdf模板生成pdf

1.制作pdf模板

1.1下载Adobe Acrobat DC

官网比较慢 百度网盘永久链接

https://pan.baidu.com/s/1JnkOtudacCKqdYpHqtR-Wg
提取码 :EDG6

2.制作

  1. 使用word制作,填充完文本样式之后,转pdf
  2. 使用Adobe编辑打开
    在这里插入图片描述

点击准备表单,会自动帮你创建好表单,要是没有这个按钮,就去 更多工具 里添加

在这里插入图片描述

此按钮可以用户自定义添加表单
在这里插入图片描述
为每个表单添加唯一的别名
到此制作完成,但是使用pdf模板,无法实现添加动态表格,后续提供解决思路,不过还是不理想

3.代码

    public static void generateTempPDF() throws Exception {
        PdfReader reader = null;
        PdfStamper ps = null;
        OutputStream fos = null;
        ByteArrayOutputStream bos = null;
        try {
            String fileName = "C:\\Users\\cbh17\\Desktop\\bb1.pdf";//模板绝对路径
            reader = new PdfReader(fileName);
            bos = new ByteArrayOutputStream();
            ps = new PdfStamper(reader, bos);

            // 使用中文字体
            BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            ArrayList<BaseFont> fontList = new ArrayList<BaseFont>();
            fontList.add(bf);

            AcroFields fields = ps.getAcroFields();
            fields.setSubstitutionFonts(fontList);
            fillData(fields, data());//渲染

            //必须要调用这个,否则文档不会生成的
            ps.setFormFlattening(true);
            if(ps != null){
                ps.close();
            }
            //生成pdf路径存放的路径
            fos = new FileOutputStream("C:\\Users\\cbh17\\Desktop\\bb2.pdf");
            fos.write(bos.toByteArray());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(fos!=null){
                fos.flush();
                fos.close();
            }
            if (bos != null){
                bos.close();
            }
            if(reader != null){
                reader.close();
            }
        }
    }

    /**
     * 填充模板中的数据
     */
    public static void fillData(AcroFields fields, Map<String, String> data) {
        try {
            for (String key : data.keySet()) {
                String value = data.get(key);
                // 为字段赋值,注意字段名称是区分大小写的
                fields.setField(key, value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 填充数据源
     * 其中data存放的key值与pdf模板中的文本域值相对应
     */
    public static Map<String, String> data() {
        Map<String, String> data = new HashMap<String, String>();
        //key要与模板中的别名一一对应
        data.put("customerName", "bb2");
        data.put("houseName", "bb2");
        data.put("buildArea", "2020/7");
        data.put("code", "2020/7");
        data.put("operateDate", "2020/7");
        data.put("chargeEndDate", "2020/7");
        return data;
    }

 至此模板填充完毕,但是使用 pdf模板 无法制作动态的 表格,因为并不能预知有多少数据,所以别名就不知道要用多少

3.通过pdf模板制作 除了表格以外的 临时文件,然后解析临时文件再进行填充

3.1代码

private void exportOrderDetailPdf()throws Exception {
        List<String> pdfData = analysisPDF();
        List<HashMap<String, String>> tableData = data();
        generateNewPDF(pdfData,tableData);
    }
	
	/**
	* 解析 临时文件
	* 不清楚itext 有没有获取类似 line对象的办法,保证样式不丢失,否则只能获取文本
	* 这里 我是在模板中 加入了一个 table 字符串 用作表格位置的标识
	*/
    private List<String> analysisPDF() throws Exception{
        String tempFilePath = "C:\\Users\\cbh17\\Desktop\\bb2.pdf";//临时文件路径
        File tempFile = new File(tempFilePath);
        PdfReader reader = null;
        List<String> list = new ArrayList<String>();
        FileInputStream fileInputStream = null;
        boolean deleteSign = true;
        try {
            fileInputStream = new FileInputStream(tempFile);
            reader = new PdfReader(fileInputStream);
            int pageNum = reader.getNumberOfPages();
            String pageContent = "";
            for (int i = 1; i <= pageNum; i++) {// 只能从第1页开始读
                pageContent += PdfTextExtractor.getTextFromPage(reader, i);
            }
            String[] strArr = pageContent.split("\n");
            list = Arrays.asList(strArr);
        }catch (Exception e){
            e.printStackTrace();
            deleteSign = false;
        }finally {
            if (reader!=null){
                reader.close();
            }
            if(fileInputStream!=null){
                fileInputStream.close();
            }
            if(tempFile.exists() && deleteSign){
                tempFile.delete();
            }
        }
        return list;
    }

	/**
	*制作假数据
	*/
    private List<HashMap<String,String>> data(){
        List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
        int x = 0;
        while (x < 10) {
            HashMap<String, String> map = new HashMap<String, String>();
            map.put("Key1", "Value1");
            map.put("Key2", "Value2");
            map.put("Key3", "Value3");
            map.put("Key4", "Value4");
            map.put("Key5", "Value5");
            map.put("Key6", "Value6");
            map.put("Key7", "Value7");
            map.put("Key8", "Value8");
            list.add(map);
            x++;
        }

        return list;
    }

	/**
	* 生成pdf 
	* 有两种情况
	* 一种是获取 临时文件的流对象,然后对其做 增 的操作,因此后续添加的 内容只能在后边 不能插入
	* 水印也会覆盖临时文件的内容,
	* 另一种就是 我这种,获取临时文件的文本,然后 一起生成
	*/
    private void generateNewPDF(List<String> pdfData, List<HashMap<String, String>> tableData) throws Exception {
        Document document = new Document();
        FileOutputStream fileOutputStream = null;
        PdfWriter writer = null;
        try {
            File file = new File("C:\\Users\\cbh17\\Desktop\\bb3.pdf");
            file.createNewFile();
            fileOutputStream = new FileOutputStream(file);
            writer = PdfWriter.getInstance(document, fileOutputStream);
            writer.setPageEvent(new Watermark("LeaSoft"));// 水印

            document.open();
            BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            Font font = new Font(bf, 10, Font.NORMAL, BaseColor.BLACK);

            for (String str : pdfData) {
                if(str.equalsIgnoreCase(TABLE_SIGN)){
                    PdfPTable table = new PdfPTable(new float[] { 100, 100, 100, 100, 100, 100, 100, 100 });
                    table.setLockedWidth(true);
                    table.setTotalWidth(550);
                    table.addCell(createCell("XXXXXXXX", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
                    table.addCell(createCell("XXXXX", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,3,0,0));
                    table.addCell(createCell("XXXXXX", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
                    table.addCell(createCell("XXXXX", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
                    table.addCell(createCell("XXXXX", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
                    table.addCell(createCell("XXXXX", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
                    for (HashMap<String, String> tableDatum : tableData) {
                            table.addCell(createCell(tableDatum.get("Key1"), font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
                            table.addCell(createCell(tableDatum.get("Key2"), font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
                            table.addCell(createCell(tableDatum.get("Key3"), font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
                            table.addCell(createCell(tableDatum.get("Key4"), font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
                            table.addCell(createCell(tableDatum.get("Key5"), font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
                            table.addCell(createCell(tableDatum.get("Key6"), font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
                            table.addCell(createCell(tableDatum.get("Key7"), font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
                            table.addCell(createCell(tableDatum.get("Key8"), font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
                    }
                    table.addCell(createCell("hhh", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,6,3,0));

                    table.addCell(createCell("a", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
                    table.addCell(createCell("a", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));

                    table.addCell(createCell("a", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
                    table.addCell(createCell("a", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));

                    table.addCell(createCell("a", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
                    table.addCell(createCell("a", font, Element.ALIGN_CENTER, PdfPCell.ALIGN_MIDDLE,0,0,0));
                    document.add(table);
                }else{
                    Paragraph paragraph = new Paragraph(str, new Font(bf, 11, Font.BOLD, BaseColor.BLACK));
                    paragraph.setAlignment(PdfPCell.ALIGN_LEFT);
                    paragraph.setLeading(14f); //行间距
                    document.add(paragraph);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(document!=null && document.isOpen()){
                document.close();
            }
            if (writer!=null && !writer.isCloseStream()){
                writer.close();
            }
            if (fileOutputStream!=null){
                fileOutputStream.close();
            }
        }
    }

    /**
     *
     * @param value 文本
     * @param font 字体
     * @param horizontalAlignment 水平样式 0-left, 1-center, 2-right
     * @param verticalAlignment 垂直样式  4-top, 5-middle, 6-bottom;
     * @param colspan 列合并
     * @param rowspan 行合并
     * @param borderSide 外边框
     *  0-默认
     *  1-隐藏上边框
     *  2-隐藏下边框
     *  3-隐藏上、下边框
     *  4-隐藏左边框
     *  5-隐藏左、上边框
     *  6-隐藏左、下边框
     *  7-隐藏左、上、下边框
     *  8-隐藏右边框
     *  9-隐藏右、上边框
     *  10-隐藏右、下边框
     *  11-隐藏右、上、下边框
     *  12-隐藏左、右边框
     *  13-隐藏上、左、右边框
     *  14-隐藏下、左、右边框
     *  15-隐藏全部
     * @return
     */
    public static PdfPCell createCell(String value, Font font, int horizontalAlignment, int verticalAlignment, int colspan, int rowspan, int borderSide) {
        PdfPCell cell = new PdfPCell();

        cell.setPhrase(new Phrase(value, font));
        cell.setHorizontalAlignment(horizontalAlignment);//水平居中
        if(verticalAlignment>0){
            cell.setUseAscender(true);//垂直居中
        }
        cell.setVerticalAlignment(verticalAlignment);//垂直居中
        if(colspan>0 ){
            cell.setColspan(colspan);
        }
        if(rowspan>0){
            cell.setRowspan(rowspan);
        }
        if(borderSide>0){
            cell.disableBorderSide(borderSide);
        }
        return cell;
    }
  • 8
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值