前言

在java开发的过程中会遇到太多太多文档pdf导出,excle导出等业务场景,时隔三个月或半年来一次每一次遇到这样的业务场景对我都是非常痛苦的过程,本文旨在记录工具类使用方法和技术分享。


一、itextpdf是什么?

在这里插入图片描述
itextpdf是一个开源的Java库,用于创建和操作PDF文档。使用itextpdf,您可以创建新的PDF文档或修改现有文档,添加文本和图像,创建表单等等。该库提供了广泛的功能,并经常用于企业级应用程序中根据用户输入动态生成复杂的PDF文档。它具有各种许可证选项,具体取决于您的用例,范围从AGPL到商业许可证。

itextpdf库提供了大量的方法和功能,以下是一些常用的方法:

  1. 创建PDF文档和页面:使用PdfWriter和Document对象可以创建一个新的PDF文档并添加页面。
  2. 添加内容到PDF文档:使用Paragraph、Phrase和Chunk对象可以向PDF文档中添加文本内容。同时,也可以添加图片、表格等其它类型的内容。
  3. 创建表格:使用PdfPTable对象可以创建表格,并向其中添加行和单元格。
  4. 设置页眉页脚:使用HeaderFooter对象可以设置PDF文档的页眉和页脚,以及页码等信息。
  5. 创建书签:使用PdfOutline对象可以创建PDF文档的书签,方便用户在浏览器中导航。
  6. 导出PDF文档:使用PdfWriter对象可以将PDF文档导出为文件或流。

二、快速开始

1.废话不多说,效果先上一波

下列数据均为测试虚拟数据,不具有任何真实性

在这里插入图片描述

2.依赖引入

<!--itext5-->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf.tool</groupId>
            <artifactId>xmlworker</artifactId>
            <version>5.5.11</version>
        </dependency>

3.模版加载

在这里插入图片描述
rescources-templates-创建一个pdf模版,如果没有定制内容,直接为空白即可


3.1模版加载工具类PDF
	/**
	 * 字体对象
	 */
	public static BaseFont bfChinese;

    /**
     * 定义全局的字体静态变量
     */
    public static Font titlefont;
    public static Font titleSecondFont;
    public static Font headfont;
    public static Font secondHeadfont;
    public static Font textfont;
    public static Font secondTitleFont;
    public static Font itemFont;
    public static Font paragraphFont;
    public static Font tableCellFont;
    public static Font accessoryFont;

    /**
     * 间距
     */
    public static String shortSpacing = "      ";
    public static String mediumSpacing = "            ";
    public static String longSpacing = "                        ";
    public static String maxLongSpacing = "                                    ";
    public static String shortSlash = "   /   ";
    public static String mediumSlash = "      /      ";
    public static String longSlash = "            /            ";
    public static String maxLongSlash = "                  /                  ";

    /**
     * 模版
     */
    public static String ht;
    public static String scan;
    public static String htScan;
    public static String over;
    public static String htSign;
    public static String signatureHt;
    public static File htFile;
    public static File overFile;
    public static File htSignFile;

    /**
     * 初始化字体及勾选、未勾选图标
     */
    static {
        try {
            // 不同字体(这里定义为同一种字体:包含不同字号、不同style)
            bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            titlefont = new Font(bfChinese, 16, Font.NORMAL);
            titleSecondFont = new Font(bfChinese, 14, Font.NORMAL);
            headfont = new Font(bfChinese, 14, Font.BOLD);
            secondHeadfont = new Font(bfChinese, 15, Font.BOLD);
            textfont = new Font(bfChinese, 16, Font.NORMAL);
            secondTitleFont = new Font(bfChinese,18,Font.BOLD);
            itemFont = new Font(bfChinese,16,Font.BOLD);
            paragraphFont = new Font(bfChinese,11,Font.NORMAL);
            accessoryFont = new Font(bfChinese,13,Font.NORMAL);
            tableCellFont = new Font(bfChinese,9,Font.NORMAL);
            /**
             * 判断当前环境
             */
            String osName = System.getProperty("os.name").toLowerCase();
            if (osName.contains("win")||osName.contains("mac")) {
                ht = getResourceBasePath() + "\\templates\\ht.pdf";
                htFile = new File(ht);
            } else { //todo: linux或unbunt
                ht = "/mnt/jar/spring-cloud/ht.pdf";
                htFile = new File(ht);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取项目根路径
     *
     * @return
     */
    public static String getResourceBasePath() {
        // 获取根目录
        File path = null;
        try {
            path = new File(ResourceUtils.getURL("classpath:").getPath());
        } catch (FileNotFoundException e) {

        }

        if (path == null || !path.exists()) {
            path = new File("");
        }

		//todo: 就获取第三步中模版所在的位置,请看上列中 “3.模版加载里的内容”
        File file = new File(path.getAbsolutePath() + "\\templates");
        if (!file.exists()){
            return path.getAbsolutePath().replace("xx","xx");
        }
        return path.getAbsolutePath();
    }

4.PDF操作工具类方法

public static PdfPTable createTable() throws DocumentException {
        PdfPTable table = new PdfPTable(2);
        // 设置总宽度
        table.setTotalWidth(490);
        table.setLockedWidth(true);
        // 设置每一列宽度
        table.setTotalWidth(new float[] {240,240});
        table.setLockedWidth(true);
        return table;
    }
    public PdfPTable createTable(int numColumns) {
        PdfPTable table = new PdfPTable(numColumns);
        // 设置总宽度
        table.setTotalWidth(490);
        table.setLockedWidth(true);
        return table;
    }

    public static PdfPTable createTitleTable(int numColumns,Font font, String ... titles) {
        PdfPTable table = new PdfPTable(numColumns);
        // 设置总宽度
        table.setTotalWidth(490);
        table.setLockedWidth(true);

        for (String title : titles) {
            addTitleCell(table,title,1,font);
        }
        return table;
    }

    /**
     * 添加居中 title
     * @param document
     * @param text
     * @throws DocumentException
     * todo: 字体大小16px
     */
    public static void addTitle(Document document, String text, int alignment) throws DocumentException {
        Paragraph paragraph = new Paragraph(text, new Font(bfChinese, 16, Font.NORMAL));
        paragraph.setAlignment(alignment); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setIndentationLeft(0); //设置左缩进
        paragraph.setIndentationRight(0); //设置右缩进
        paragraph.setFirstLineIndent(0); //设置首行缩进
        paragraph.setLeading(10f); //行间距
        paragraph.setSpacingBefore(10f); //设置段落上空白
        paragraph.setSpacingAfter(10f); //设置段落下空白
        document.add(paragraph);
    }

    /**
     * 添加一级标题
     * @param document
     * @param text
     * @throws DocumentException
     */
    public static void addFirstTitle(Document document,String text,int alignment) throws DocumentException {
        Paragraph paragraph = new Paragraph(text, new Font(bfChinese, 14, Font.NORMAL));
        paragraph.setAlignment(alignment); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setIndentationLeft(0); //设置左缩进
        paragraph.setIndentationRight(0); //设置右缩进
        paragraph.setFirstLineIndent(0); //设置首行缩进
        paragraph.setLeading(7f); //行间距
        paragraph.setSpacingBefore(20f); //设置段落上空白
        paragraph.setSpacingAfter(7f); //设置段落下空白
        document.add(paragraph);
    }

    /**
     * 添加二级标题
     * @param document
     * @param text
     * @throws DocumentException
     */
    public static void addSecondTitle(Document document,String text,Font font,int alignment) throws DocumentException {
        Paragraph paragraph = new Paragraph(text, new Font(bfChinese, 12, Font.NORMAL));
        paragraph.setAlignment(alignment); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setIndentationLeft(9); //设置左缩进
        paragraph.setIndentationRight(0); //设置右缩进
        paragraph.setFirstLineIndent(9); //设置首行缩进
        paragraph.setLeading(15f); //行间距
        paragraph.setSpacingBefore(10f); //设置段落上空白
        paragraph.setSpacingAfter(5f); //设置段落下空白
        document.add(paragraph);
    }

    /**
     * 添加分割线
     * @param document
     * @throws DocumentException
     */
    public static void addLine(Document document) throws DocumentException {
        LineSeparator ls = new LineSeparator();
        ls.setLineWidth(1);
        ls.setLineColor(new BaseColor(179,180,164));
        Chunk chunk = new Chunk(ls);
        document.add(chunk);
    }

    public static void addNoBorderCell(PdfPTable table,String text) {
        PdfPCell cell = new PdfPCell(new Paragraph(text,paragraphFont));
        cell.setBorderWidth(0);
        cell.setLeading(24,0); //行间距
        table.addCell(cell);
    }

    public static void addTitleCell(PdfPTable table,String text,float borderWidth,Font font) {
        Paragraph paragraph = new Paragraph(text, font);
        paragraph.setAlignment(1);
        paragraph.setLeading(5f);
        PdfPCell cell = new PdfPCell(paragraph);
        cell.setBorderWidth(borderWidth);
        cell.setBackgroundColor(new BaseColor(245,247,251));
        cell.setHorizontalAlignment(1);
        cell.setVerticalAlignment(1);
        table.addCell(cell);
    }

    public static void addCell(PdfPTable table,String text,float borderWidth,Font font) {
        if (StringUtils.isBlank(text)) {
            text = " ";
        }
        Paragraph paragraph = new Paragraph(text, font);
        paragraph.setAlignment(1);
        PdfPCell cell = new PdfPCell(paragraph);
        //水平居中和垂直居中
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setUseAscender(true);
        table.addCell(cell);
    }

    public static void addCell(PdfPTable table, BigDecimal amount, float borderWidth, Font font) {
        Paragraph paragraph = null;
        if (Objects.isNull(amount)) {
            paragraph = new Paragraph(" ",font);
        } else {
            paragraph = new Paragraph(amount.toString(),font);
        }

        paragraph.setAlignment(1);
        PdfPCell cell = new PdfPCell(paragraph);
        cell.setBorderWidth(borderWidth);
        //水平居中和垂直居中
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setUseAscender(true);
        table.addCell(cell);
    }

    /**
     * 添加二级标题
     * @param document
     * @param text
     * @throws DocumentException
     */
    public void addSecondTitle(Document document,String text,int alignment,float spacingBefore,float spacingAfter) throws DocumentException {
        Paragraph paragraph10 = new Paragraph(text, secondTitleFont);
        paragraph10.setAlignment(alignment); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph10.setIndentationLeft(12); //设置左缩进
        paragraph10.setIndentationRight(12); //设置右缩进
        paragraph10.setFirstLineIndent(32); //设置首行缩进
        paragraph10.setLeading(30f); //行间距
        paragraph10.setSpacingBefore(1f); //设置段落上空白
        paragraph10.setSpacingAfter(15f); //设置段落下空白
        document.add(paragraph10);
    }

    /**
     * 添加子项标题
     * @param document
     * @param text
     * @throws DocumentException
     */
    public void addItemTitle(Document document,String text) throws DocumentException {
        Paragraph paragraph = new Paragraph(text, itemFont);
        paragraph.setAlignment(0); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setIndentationLeft(12); //设置左缩进
        paragraph.setIndentationRight(12); //设置右缩进
        paragraph.setFirstLineIndent(32); //设置首行缩进
        paragraph.setLeading(30f); //行间距
        paragraph.setSpacingBefore(1f); //设置段落上空白
        paragraph.setSpacingAfter(1f); //设置段落下空白
        document.add(paragraph);
    }

    /**
     * 添加段落 自动换行
     */
    public void addTextParagraph(Document document,String text) throws DocumentException {
        Paragraph paragraph = new Paragraph(text,paragraphFont);
        paragraph.setAlignment(0); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setIndentationLeft(12); //设置左缩进
        paragraph.setIndentationRight(12); //设置右缩进
        paragraph.setFirstLineIndent(32); //设置首行缩进
        paragraph.setLeading(30f); //行间距
        document.add(paragraph);
    }

    /**
     * 添加段落 自动换行
     */
    public Paragraph createTextParagraph() throws DocumentException {
        Paragraph paragraph = new Paragraph("",paragraphFont);
        paragraph.setAlignment(0); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setIndentationLeft(12); //设置左缩进
        paragraph.setIndentationRight(12); //设置右缩进
        paragraph.setFirstLineIndent(32); //设置首行缩进
        paragraph.setLeading(30f); //行间距
        return paragraph;
    }

    /**
     * 添加段落 自动换行
     */
    public Paragraph createTextParagraph(String text) throws DocumentException {
        Paragraph paragraph = new Paragraph(text,paragraphFont);
        paragraph.setAlignment(0); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setIndentationLeft(12); //设置左缩进
        paragraph.setIndentationRight(12); //设置右缩进
        paragraph.setFirstLineIndent(32); //设置首行缩进
        paragraph.setLeading(30f); //行间距
        return paragraph;
    }

    /**
     * 创建段落 自动换行
     */
    public Paragraph createTextParagraph(String text,int alignment) {
        Paragraph paragraph = new Paragraph(text,paragraphFont);
        paragraph.setAlignment(alignment); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setIndentationLeft(12); //设置左缩进
        paragraph.setIndentationRight(12); //设置右缩进
        paragraph.setFirstLineIndent(32); //设置首行缩进
        paragraph.setLeading(30f); //行间距
        return paragraph;
    }

    public void appendParagraph(Document document,Paragraph paragraph,String text) throws DocumentException {
        paragraph.add(text);
        document.add(paragraph);
    }

    /**
     * 添加下划线
     */
    public Paragraph addUnderLine(Paragraph paragraph,String text){
        if (StringUtils.isBlank(text)){
            text = shortSpacing;
        } else {
            text = StringUtils.join(" ",text," ");
        }
        Chunk sigUnderline = new Chunk(text);
        sigUnderline.setUnderline(0.1f, -2f);
        paragraph.add(sigUnderline);
        return paragraph;
    }

    /**
     * 添加下划线
     */
    public void addUnderLine(Document document,Paragraph paragraph,String text) throws DocumentException {
        if (StringUtils.isBlank(text)){
            text = shortSpacing;
        }
        Chunk sigUnderline = new Chunk(StringUtils.join(" ",text," "));
        sigUnderline.setUnderline(0.1f, -2f);
        paragraph.add(sigUnderline);
        document.add(paragraph);
    }

    /**objStmMark = null
     * 追加签名
     */
    public File mergePdf(String [] files,String savePath){
        PdfReader pdfReader = null;
        Document document = null;
        try {
            //创建一个与a.pdf相同纸张大小的document
            pdfReader = new PdfReader(files[0]);
            document = new Document(pdfReader.getPageSize(1));
            PdfCopy copy = new PdfCopy(document, new FileOutputStream(savePath));
            document.open();
            for (int i = 0; i < files.length; i++) {
                //一个一个的遍历现有的PDF
                PdfReader reader = new PdfReader(files[i]);
                int n = reader.getNumberOfPages();//PDF文件总共页数
                System.out.println("n:"+n);
                for (int j = 1; j <= n; j++) {
                    document.newPage();
                    PdfImportedPage page = copy.getImportedPage(reader, j);
                    copy.addPage(page);
                }
                reader.close();
            }
            document.close();
            pdfReader.close();
            return new File(savePath);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        } finally {
            document.close();
            pdfReader.close();
        }
        return null;
    }


    /**
     * 添加下划线
     */
    public Paragraph addUnderLine(Boolean check,Paragraph paragraph,String text1,String text2){
        Chunk sigUnderline = null;
        if (check){
            if (Objects.isNull(text1)){
                text1 = shortSpacing;
            } else {
                text1 = StringUtils.join(" ",text1," ");
            }
            sigUnderline = new Chunk(text1);
        } else {
            if (Objects.isNull(text2)){
                text2 = shortSpacing;
            } else {
                text2 = StringUtils.join(" ",text2," ");
            }
            sigUnderline = new Chunk(text2);
        }
        sigUnderline.setUnderline(0.1f, -2f);
        paragraph.add(sigUnderline);
        return paragraph;
    }

    /**
     * 添加下划线
     */
    public void addUnderLine(Document document,Boolean check,Paragraph paragraph,String text1,String text2) throws DocumentException {
        Chunk sigUnderline = null;
        if (check){
            if (Objects.isNull(text1)){
                text1 = shortSpacing;
            } else {
                text1 = StringUtils.join(" ",text1," ");
            }
            sigUnderline = new Chunk(text1);
        } else {
            if (Objects.isNull(text2)){
                text2 = shortSpacing;
            } else {
                text2 = StringUtils.join(" ",text2," ");
            }
            sigUnderline = new Chunk(text2);
        }

        sigUnderline.setUnderline(0.1F, -2.0F);
        paragraph.add(sigUnderline);
        document.add(paragraph);
    }

    /**
     * 添加下划线 Chunk
     */
    public Chunk createUnderLineChunk(String text) {
        if (Objects.isNull(text)){
            text = shortSpacing;
        } else {
            text = StringUtils.join(" ",text," ");
        }
        Chunk sigUnderline = new Chunk(text);
        sigUnderline.setUnderline(0.1f, -2f);
        return sigUnderline;
    }

    private Document createDocument() throws IOException {
        // 1.新建document对象 建立一个Document对象
        Document document = new Document(PageSize.A4);

        //
        PdfUtils.htFile.createNewFile();

        // 3.打开文档
        document.open();
        document.addTitle("销售合同");// 标题
        document.addAuthor("chuz");// 作者
        document.addSubject("Subject@iText pdf sample");// 主题
        document.addKeywords("Keywords@iTextpdf");// 关键字
        document.addCreator("chuz develop");// 创建者
        return document;
    }

    /**
     * 添加下划线 Chunk
     */
    public Chunk createUnderLineChunk(Boolean check,String text1,String text2) throws DocumentException {
        Chunk sigUnderline = null;
        if (check){
            if (Objects.isNull(text1)){
                text1 = shortSpacing;
            } else {
                text1 = StringUtils.join(" ",text1," ");
            }
            sigUnderline = new Chunk(text1);
        } else {
            if (Objects.isNull(text2)){
                text2 = shortSpacing;
            } else {
                text2 = StringUtils.join(" ",text2," ");
            }
            sigUnderline = new Chunk(text2);
        }

        sigUnderline.setUnderline(0.1f, -2f);
        return sigUnderline;
    }

    /**
     * 添加下划线 Chunk
     */
    public Chunk createChunk(String text) throws DocumentException {
        if (StringUtils.isBlank(text)){
            text = shortSpacing;
        }
        text = StringUtils.join(" ",text," ");
        return new Chunk(text);
    }

    /**
     * 添加带选择框文本
     */
//    public void addCheck(Document document,Boolean check,String text) throws Exception {
//        Paragraph paragraph = createTextParagraph("");
//        if (check){
//            paragraph.add(new Chunk(checkPng,0,0,true));
//        } else {
//            paragraph.add(new Chunk(unCheckPng,0,0,true));
//        }
//        Chunk chunk = new Chunk(StringUtils.join(" ",text),textfont);
//        paragraph.add(chunk);
//        document.add(paragraph);
//    }

    /**
     * 添加带选择框文本
     */
//    public void addCheck(Paragraph paragraph,Boolean check,String text) throws Exception {
//        if (check){
//            paragraph.add(new Chunk(checkPng,0,0,true));
//        } else {
//            paragraph.add(new Chunk(unCheckPng,0,0,true));
//        }
//        Chunk chunk = new Chunk(StringUtils.join(" ",text),textfont);
//        paragraph.add(chunk);
//    }

    /**
     * 添加带选择框文本
     */
//    public Paragraph addCheck(Boolean check,String text) throws Exception {
//        Paragraph paragraph = createTextParagraph("");
//        if (check){
//            paragraph.add(new Chunk(checkPng,0,0,true));
//        } else {
//            paragraph.add(new Chunk(unCheckPng,0,0,true));
//        }
//        Chunk chunk = new Chunk(StringUtils.join(" ",text),textfont);
//        paragraph.add(chunk);
//        return paragraph;
//    }

    /**
     * 添加带选择框文本
     */
//    public Paragraph appendCheck(Paragraph paragraph,Boolean check,String text) throws Exception {
//        if (check){
//            paragraph.add(new Chunk(checkPng,0,0,true));
//        } else {
//            paragraph.add(new Chunk(unCheckPng,0,0,true));
//        }
//        Chunk chunk = new Chunk(StringUtils.join(" ",text),textfont);
//        paragraph.add(chunk);
//        return paragraph;
//    }

    public void packageDateParagraph(Document document, Paragraph paragraph, Date date) throws DocumentException {
        if (Objects.nonNull(date)){
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);

            int year = calendar.get(Calendar.YEAR);
            int month = calendar.get(Calendar.MONTH) + 1;
            int day = calendar.get(Calendar.DAY_OF_MONTH);

            addUnderLine(paragraph,StringUtils.join(year));
            paragraph.add("年");
            addUnderLine(paragraph,StringUtils.join(month));
            paragraph.add("月");
            addUnderLine(paragraph,StringUtils.join(day));
            paragraph.add("日");
        } else {
            addUnderLine(paragraph,StringUtils.join(shortSlash));
            paragraph.add("年");
            addUnderLine(paragraph,StringUtils.join(shortSlash));
            paragraph.add("月");
            addUnderLine(paragraph,StringUtils.join(shortSlash));
            paragraph.add("日");
        }
        document.add(paragraph);
    }

    public MultipartFile fileToMultipartFile(File file) {
        FileItem fileItem = createFileItem(file);
        MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
        return multipartFile;
    }

    public static FileItem createFileItem(File file) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item = factory.createItem("textField", "text/plain", true, file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return item;
    }

    public String precision(BigDecimal number){
        if (Objects.nonNull(number)){
            return number.setScale(0,BigDecimal.ROUND_DOWN).toString();
        }
        return null;
    }

5.完整代码

5.1前端代码-Vue
	downloadPdf(){
      api.downloadPdf({
        fileName: this.data.contractName+'.pdf',
        params: {type:'0',contractId:this.data.id}
      })
    },
5.2控制层代码
@GetMapping(value = "create")
    public void create(@ApiParam(value = "0:销售合同,1:第三方合同") @RequestParam(name = "type") String type,
                       @RequestParam(name = "contractId") String contractId,
                       HttpServletResponse response) throws IOException {
        File pdfFile = null;
        if ("0".equals(type)) {
            /* 合同条款 */
           	
           	//到业务方法 xx代替,这里主要是根据条件查询从表信息
            List<xxx> 1 =getXXX();
            //设计到业务方法 xx代替,这里主要是根据条件查询从表信息
            List<xxx> 1 =getXXX();
            // 仪表经验计费条款
            List<xxx> 1 =getXXX();

            /* 其它费用 */
            List<xxx> 1 =getXXX();
			//导出方法
            pdfFile = contractPdfService.createContractInfo(createContractInfo);
        } 
        response.setContentType("application/pdf");
        if (pdfFile.exists()) {
            FileInputStream in = new FileInputStream(pdfFile);
            OutputStream out = response.getOutputStream();
            byte[] b = new byte[1024 * 5];
            int n;
            while ((n = in.read(b)) != -1) {
                out.write(b, 0, n);
            }
            out.flush();
            in.close();
            out.close();
        }
    }

5.3业务层代码
public File createContractInfo(CreateContractInfo contractInfo){
        try {
            // 1.新建document对象 建立一个Document对象
            Document document = new Document(PageSize.A4);

            PdfUtils.htFile.createNewFile();
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(PdfUtils.htFile));

            // 3.打开文档
            document.open();
            document.addTitle(contractInfo.getContractName());// 标题
            document.addAuthor("chuz");// 作者
            document.addSubject("Subject@iText pdf sample");// 主题
            document.addKeywords("Keywords@iTextpdf");// 关键字
            document.addCreator("chuz develop");// 创建者

            // 4.向文档中添加内容
            generatePDF(document,contractInfo);
            // 5.关闭文档
            document.close();
            writer.close();

            return PdfUtils.htFile;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return PdfUtils.htFile;
    }

// 生成PDF文件
    public void generatePDF(Document document,CreateContractInfo contractInfo) throws Exception {
        //添加总标题,
        PdfUtils.addTitle(document,contractInfo.getContractName(),1);
        // 基本信息-一级标题
        PdfUtils.addFirstTitle(document,"(一)基本信息",0);

        PdfPTable table = PdfUtils.createTable();
        PdfUtils.addNoBorderCell(table,StringUtils.join("合同编号:",contractInfo.getContractNo()));
        PdfUtils.addNoBorderCell(table,StringUtils.join("出租方:",contractInfo.getFirstPartyName()));
        PdfUtils.addNoBorderCell(table,StringUtils.join("出租方:",contractInfo.getFirstPartyName()));
        PdfUtils.addNoBorderCell(table,StringUtils.join("租赁方:",contractInfo.getPartyBName()));
        PdfUtils.addNoBorderCell(table,StringUtils.join("经办人:",contractInfo.getHandledByName()));
        PdfUtils.addNoBorderCell(table,StringUtils.join("签订日期:", DateFormatUtil.dateToString(DateFormatUtil.yyyy_MM_dd,contractInfo.getSigningTime())));
        PdfUtils.addNoBorderCell(table,StringUtils.join("业态:",contractInfo.getContractTypeName()));
        PdfUtils.addNoBorderCell(table,StringUtils.join("意向来源:",dictTrans("customer_source",contractInfo.getContractSource())));
        PdfUtils.addNoBorderCell(table,StringUtils.join("合同标签:",contractInfo.getContractLabel()));
        PdfUtils.addNoBorderCell(table,StringUtils.join("租赁日期:",StringUtils.join(
                DateFormatUtil.dateToString(DateFormatUtil.yyyy_MM_dd,contractInfo.getStartTime()),
                "~",
                DateFormatUtil.dateToString(DateFormatUtil.yyyy_MM_dd,contractInfo.getEndTime()))));
        document.add(table);
        PdfUtils.addLine(document);


        // 合同条款-一级标题
        PdfUtils.addFirstTitle(document,"(二)合同条款",0);

        PdfUtils.addSecondTitle(document,"合同计费条款",PdfUtils.titleSecondFont,0);
        PdfPTable itemTable = PdfUtils.createTitleTable(5,PdfUtils.tableCellFont,"资源","收费项","计费方式","计费周期","计算方式");
        for (FreeContractClauseDto contractClauseDto : contractInfo.getContractClauseDtos()) {
            PdfUtils.addCell(itemTable,contractClauseDto.getHouseName(),1,PdfUtils.tableCellFont);
            PdfUtils.addCell(itemTable,contractClauseDto.getSetName(),1,PdfUtils.tableCellFont);
            PdfUtils.addCell(itemTable,dictTrans("free_calculate_way",contractClauseDto.getCalculateWay()),1,PdfUtils.tableCellFont);
            PdfUtils.addCell(itemTable,dictTrans("charging_cycle",contractClauseDto.getChargingCycle()),1,PdfUtils.tableCellFont);
            PdfUtils.addCell(itemTable,contractClauseDto.getFreeRemarks(),1,PdfUtils.tableCellFont);
        }
        document.add(itemTable);

        PdfUtils.addSecondTitle(document,"仪表/经营计费条款",PdfUtils.titleSecondFont,0);
        PdfPTable deviceTable = PdfUtils.createTitleTable(4,PdfUtils.tableCellFont,"资源","收费项","计费方式","仪表/录数项");
        for (FreeContractClauseDto deviceContractClauseDto : contractInfo.getDeviceContractClauseDtos()) {
            PdfUtils.addCell(deviceTable,deviceContractClauseDto.getHouseName(),1,PdfUtils.tableCellFont);
            PdfUtils.addCell(deviceTable,deviceContractClauseDto.getSetName(),1,PdfUtils.tableCellFont);
            PdfUtils.addCell(deviceTable,deviceContractClauseDto.getChargeStandard(),1,PdfUtils.tableCellFont);
            PdfUtils.addCell(deviceTable,deviceContractClauseDto.getMeterNo(),1,PdfUtils.tableCellFont);
        }
        document.add(deviceTable);

        PdfUtils.addSecondTitle(document,"其他费用添加",PdfUtils.titleSecondFont,0);
        PdfPTable elseFreeTable = PdfUtils.createTitleTable(8,PdfUtils.tableCellFont,"资源","收费项","应收(元)","实收(元)","欠收(元)","应收日期","账期","备注");
        for (FreeBillDetailVo elseFreeBillDetailVo : contractInfo.getElseFreeBillDetailVos()) {
            PdfUtils.addCell(elseFreeTable,elseFreeBillDetailVo.getHouseName(),1,PdfUtils.tableCellFont);
            PdfUtils.addCell(elseFreeTable,"收费项",1,PdfUtils.tableCellFont);
            PdfUtils.addCell(elseFreeTable,elseFreeBillDetailVo.getOughtAmount(),1,PdfUtils.tableCellFont);
            PdfUtils.addCell(elseFreeTable,elseFreeBillDetailVo.getPracticalAmount(),1,PdfUtils.tableCellFont);
            PdfUtils.addCell(elseFreeTable,elseFreeBillDetailVo.getOweAmount(),1,PdfUtils.tableCellFont);
            PdfUtils.addCell(elseFreeTable,DateFormatUtil.dateToString(DateFormatUtil.yyyy_MM_dd,elseFreeBillDetailVo.getOughtDate()),1,PdfUtils.tableCellFont);
            PdfUtils.addCell(elseFreeTable,elseFreeBillDetailVo.getPeriod(),1,PdfUtils.tableCellFont);
            PdfUtils.addCell(elseFreeTable,elseFreeBillDetailVo.getRemarks(),1,PdfUtils.tableCellFont);
        }
        document.add(elseFreeTable);


        PdfUtils.addLine(document);

        // 其它约定
        PdfUtils.addFirstTitle(document,"(三)其它约定",0);
        PdfPTable elseTable = PdfUtils.createTable();
        PdfUtils.addNoBorderCell(elseTable,"设施/服务:设施/服务");
        PdfUtils.addNoBorderCell(elseTable,"特殊约定:特殊约定");
        PdfUtils.addNoBorderCell(elseTable,"违约说明:违约说明");
        PdfUtils.addNoBorderCell(elseTable,"");
        document.add(elseTable);
        PdfUtils.addLine(document);

        // 合同账单-自定义
        Paragraph paragraph = new Paragraph("(四)合同账单", new Font(PdfUtils.bfChinese, 14, Font.NORMAL));
        paragraph.setAlignment(0); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setIndentationLeft(0); //设置左缩进
        paragraph.setIndentationRight(0); //设置右缩进
        paragraph.setFirstLineIndent(0); //设置首行缩进
        paragraph.setLeading(7f); //行间距
        paragraph.setSpacingBefore(20f); //设置段落上空白
        paragraph.setSpacingAfter(25f); //设置段落下空白
        document.add(paragraph);

        PdfPTable billTable = PdfUtils.createTitleTable(10,PdfUtils.tableCellFont,"费用项目","费用类型","费用标识","账期","起止时间","应收金额(元)","实收金额(元)","欠费金额(元)","缴费时间","状态");
        List<FreeBillDetailVo> freeBillDetailVos = contractInfo.getFreeBillDetailVos();
        for (FreeBillDetailVo freeBillDetailVo : freeBillDetailVos) {
            PdfUtils.addCell(billTable,"租金",1,PdfUtils.tableCellFont);
            PdfUtils.addCell(billTable,"租金",1,PdfUtils.tableCellFont);
            PdfUtils.addCell(billTable,"周期性收费",1,PdfUtils.tableCellFont);
            PdfUtils.addCell(billTable,freeBillDetailVo.getPeriod(),1,PdfUtils.tableCellFont);

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String dateTime=sdf.format(freeBillDetailVo.getBeginTime())+"~"+sdf.format(freeBillDetailVo.getEndTime());
            PdfUtils.addCell(billTable,dateTime,1,PdfUtils.tableCellFont);
            PdfUtils.addCell(billTable,freeBillDetailVo.getPracticalAmount(),1,PdfUtils.tableCellFont);
            PdfUtils.addCell(billTable,freeBillDetailVo.getOughtAmount(),1,PdfUtils.tableCellFont);
            PdfUtils.addCell(billTable,freeBillDetailVo.getOweAmount(),1,PdfUtils.tableCellFont);
            PdfUtils.addCell(billTable,DateFormatUtil.dateToString(DateFormatUtil.yyyy_MM_dd_HHmmss,freeBillDetailVo.getPayTime()),1,PdfUtils.tableCellFont);
            PdfUtils.addCell(billTable,"未结清",1,PdfUtils.tableCellFont);
        }
        document.add(billTable);
    }
5.4PDF工具类完整代码
public class PdfUtils {

    public static BaseFont bfChinese;

    /**
     * 定义全局的字体静态变量
     */
    public static Font titlefont;
    public static Font titleSecondFont;
    public static Font headfont;
    public static Font secondHeadfont;
    public static Font textfont;
    public static Font secondTitleFont;
    public static Font itemFont;
    public static Font paragraphFont;
    public static Font tableCellFont;
    public static Font accessoryFont;

    /**
     * 图标
     */
//    public static Image checkPng;
//    public static Image unCheckPng;

    /**
     * 间距
     */
    public static String shortSpacing = "      ";
    public static String mediumSpacing = "            ";
    public static String longSpacing = "                        ";
    public static String maxLongSpacing = "                                    ";
    public static String shortSlash = "   /   ";
    public static String mediumSlash = "      /      ";
    public static String longSlash = "            /            ";
    public static String maxLongSlash = "                  /                  ";

    /**
     * 模版
     */
    public static String ht;
    public static String scan;
    public static String htScan;
    public static String over;
    public static String htSign;
    public static String signatureHt;
    public static File htFile;
    public static File overFile;
    public static File htSignFile;

    /**
     * 初始化字体及勾选、未勾选图标
     */
    static {
        try {
            // 不同字体(这里定义为同一种字体:包含不同字号、不同style)
            bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            titlefont = new Font(bfChinese, 16, Font.NORMAL);
            titleSecondFont = new Font(bfChinese, 14, Font.NORMAL);
            headfont = new Font(bfChinese, 14, Font.BOLD);
            secondHeadfont = new Font(bfChinese, 15, Font.BOLD);
            textfont = new Font(bfChinese, 16, Font.NORMAL);
            secondTitleFont = new Font(bfChinese,18,Font.BOLD);
            itemFont = new Font(bfChinese,16,Font.BOLD);
            paragraphFont = new Font(bfChinese,11,Font.NORMAL);
            accessoryFont = new Font(bfChinese,13,Font.NORMAL);
            tableCellFont = new Font(bfChinese,9,Font.NORMAL);
            /**
             * 判断当前环境
             */
            String osName = System.getProperty("os.name").toLowerCase();
            if (osName.contains("win")||osName.contains("mac")) {
//                checkPng = Image.getInstance(getResourceBasePath() + "\\templates\\check.png");
//                checkPng.scaleAbsolute(14,12);
//                unCheckPng = Image.getInstance(getResourceBasePath() + "\\templates\\unCheck.png");
//                unCheckPng.scaleAbsolute(14,12);

                ht = getResourceBasePath() + "\\templates\\ht.pdf";
                scan = getResourceBasePath() + "\\templates\\scan.pdf";
                htScan = getResourceBasePath() + "\\templates\\htScan.pdf";
                over = getResourceBasePath() + "\\templates\\over.pdf";
                htSign = getResourceBasePath() + "\\templates\\htSign.pdf";
                htFile = new File(ht);
                overFile = new File(over);
                htSignFile = new File(htSign);
            } else { //todo: linux或unbunt
//                checkPng = Image.getInstance("/mnt/jar/chuz-cloud-school/check.png");
//                checkPng.scaleAbsolute(14,12);
//                unCheckPng = Image.getInstance("/mnt/jar/chuz-cloud-school/unCheck.png");
//                unCheckPng.scaleAbsolute(14,12);

                ht = "/mnt/jar/chuz-cloud-school/ht.pdf";
                scan = "/mnt/jar/chuz-cloud-school/scan.pdf";
                htScan = "/mnt/jar/chuz-cloud-school/htScan.pdf";
                over = "/mnt/jar/chuz-cloud-school/over.pdf";
                htSign = "/mnt/jar/chuz-cloud-school/htSign.pdf";

                htFile = new File(ht);
                overFile = new File(over);
                htSignFile = new File(htSign);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取项目根路径
     *
     * @return
     */
    public static String getResourceBasePath() {
        // 获取根目录
        File path = null;
        try {
            path = new File(ResourceUtils.getURL("classpath:").getPath());
        } catch (FileNotFoundException e) {

        }

        if (path == null || !path.exists()) {
            path = new File("");
        }

        File file = new File(path.getAbsolutePath() + "\\templates");
        if (!file.exists()){
            return path.getAbsolutePath().replace("chuz-cloud-module\\chuz-cloud-school-start","chuz-boot-module-school");
        }
        return path.getAbsolutePath();
    }

    public static PdfPTable createTable() throws DocumentException {
        PdfPTable table = new PdfPTable(2);
        // 设置总宽度
        table.setTotalWidth(490);
        table.setLockedWidth(true);
        // 设置每一列宽度
        table.setTotalWidth(new float[] {240,240});
        table.setLockedWidth(true);
        return table;
    }
    public PdfPTable createTable(int numColumns) {
        PdfPTable table = new PdfPTable(numColumns);
        // 设置总宽度
        table.setTotalWidth(490);
        table.setLockedWidth(true);
        return table;
    }

    public static PdfPTable createTitleTable(int numColumns,Font font, String ... titles) {
        PdfPTable table = new PdfPTable(numColumns);
        // 设置总宽度
        table.setTotalWidth(490);
        table.setLockedWidth(true);

        for (String title : titles) {
            addTitleCell(table,title,1,font);
        }
        return table;
    }

    /**
     * 添加居中 title
     * @param document
     * @param text
     * @throws DocumentException
     * todo: 字体大小16px
     */
    public static void addTitle(Document document, String text, int alignment) throws DocumentException {
        Paragraph paragraph = new Paragraph(text, new Font(bfChinese, 16, Font.NORMAL));
        paragraph.setAlignment(alignment); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setIndentationLeft(0); //设置左缩进
        paragraph.setIndentationRight(0); //设置右缩进
        paragraph.setFirstLineIndent(0); //设置首行缩进
        paragraph.setLeading(10f); //行间距
        paragraph.setSpacingBefore(10f); //设置段落上空白
        paragraph.setSpacingAfter(10f); //设置段落下空白
        document.add(paragraph);
    }

    /**
     * 添加一级标题
     * @param document
     * @param text
     * @throws DocumentException
     */
    public static void addFirstTitle(Document document,String text,int alignment) throws DocumentException {
        Paragraph paragraph = new Paragraph(text, new Font(bfChinese, 14, Font.NORMAL));
        paragraph.setAlignment(alignment); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setIndentationLeft(0); //设置左缩进
        paragraph.setIndentationRight(0); //设置右缩进
        paragraph.setFirstLineIndent(0); //设置首行缩进
        paragraph.setLeading(7f); //行间距
        paragraph.setSpacingBefore(20f); //设置段落上空白
        paragraph.setSpacingAfter(7f); //设置段落下空白
        document.add(paragraph);
    }

    /**
     * 添加二级标题
     * @param document
     * @param text
     * @throws DocumentException
     */
    public static void addSecondTitle(Document document,String text,Font font,int alignment) throws DocumentException {
        Paragraph paragraph = new Paragraph(text, new Font(bfChinese, 12, Font.NORMAL));
        paragraph.setAlignment(alignment); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setIndentationLeft(9); //设置左缩进
        paragraph.setIndentationRight(0); //设置右缩进
        paragraph.setFirstLineIndent(9); //设置首行缩进
        paragraph.setLeading(15f); //行间距
        paragraph.setSpacingBefore(10f); //设置段落上空白
        paragraph.setSpacingAfter(5f); //设置段落下空白
        document.add(paragraph);
    }

    /**
     * 添加分割线
     * @param document
     * @throws DocumentException
     */
    public static void addLine(Document document) throws DocumentException {
        LineSeparator ls = new LineSeparator();
        ls.setLineWidth(1);
        ls.setLineColor(new BaseColor(179,180,164));
        Chunk chunk = new Chunk(ls);
        document.add(chunk);
    }

    public static void addNoBorderCell(PdfPTable table,String text) {
        PdfPCell cell = new PdfPCell(new Paragraph(text,paragraphFont));
        cell.setBorderWidth(0);
        cell.setLeading(24,0); //行间距
        table.addCell(cell);
    }

    public static void addTitleCell(PdfPTable table,String text,float borderWidth,Font font) {
        Paragraph paragraph = new Paragraph(text, font);
        paragraph.setAlignment(1);
        paragraph.setLeading(5f);
        PdfPCell cell = new PdfPCell(paragraph);
        cell.setBorderWidth(borderWidth);
        cell.setBackgroundColor(new BaseColor(245,247,251));
        cell.setHorizontalAlignment(1);
        cell.setVerticalAlignment(1);
        table.addCell(cell);
    }

    public static void addCell(PdfPTable table,String text,float borderWidth,Font font) {
        if (StringUtils.isBlank(text)) {
            text = " ";
        }
        Paragraph paragraph = new Paragraph(text, font);
        paragraph.setAlignment(1);
        PdfPCell cell = new PdfPCell(paragraph);
        //水平居中和垂直居中
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setUseAscender(true);
        table.addCell(cell);
    }

    public static void addCell(PdfPTable table, BigDecimal amount, float borderWidth, Font font) {
        Paragraph paragraph = null;
        if (Objects.isNull(amount)) {
            paragraph = new Paragraph(" ",font);
        } else {
            paragraph = new Paragraph(amount.toString(),font);
        }

        paragraph.setAlignment(1);
        PdfPCell cell = new PdfPCell(paragraph);
        cell.setBorderWidth(borderWidth);
        //水平居中和垂直居中
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setUseAscender(true);
        table.addCell(cell);
    }

    /**
     * 添加二级标题
     * @param document
     * @param text
     * @throws DocumentException
     */
    public void addSecondTitle(Document document,String text,int alignment,float spacingBefore,float spacingAfter) throws DocumentException {
        Paragraph paragraph10 = new Paragraph(text, secondTitleFont);
        paragraph10.setAlignment(alignment); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph10.setIndentationLeft(12); //设置左缩进
        paragraph10.setIndentationRight(12); //设置右缩进
        paragraph10.setFirstLineIndent(32); //设置首行缩进
        paragraph10.setLeading(30f); //行间距
        paragraph10.setSpacingBefore(1f); //设置段落上空白
        paragraph10.setSpacingAfter(15f); //设置段落下空白
        document.add(paragraph10);
    }

    /**
     * 添加子项标题
     * @param document
     * @param text
     * @throws DocumentException
     */
    public void addItemTitle(Document document,String text) throws DocumentException {
        Paragraph paragraph = new Paragraph(text, itemFont);
        paragraph.setAlignment(0); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setIndentationLeft(12); //设置左缩进
        paragraph.setIndentationRight(12); //设置右缩进
        paragraph.setFirstLineIndent(32); //设置首行缩进
        paragraph.setLeading(30f); //行间距
        paragraph.setSpacingBefore(1f); //设置段落上空白
        paragraph.setSpacingAfter(1f); //设置段落下空白
        document.add(paragraph);
    }

    /**
     * 添加段落 自动换行
     */
    public void addTextParagraph(Document document,String text) throws DocumentException {
        Paragraph paragraph = new Paragraph(text,paragraphFont);
        paragraph.setAlignment(0); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setIndentationLeft(12); //设置左缩进
        paragraph.setIndentationRight(12); //设置右缩进
        paragraph.setFirstLineIndent(32); //设置首行缩进
        paragraph.setLeading(30f); //行间距
        document.add(paragraph);
    }

    /**
     * 添加段落 自动换行
     */
    public Paragraph createTextParagraph() throws DocumentException {
        Paragraph paragraph = new Paragraph("",paragraphFont);
        paragraph.setAlignment(0); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setIndentationLeft(12); //设置左缩进
        paragraph.setIndentationRight(12); //设置右缩进
        paragraph.setFirstLineIndent(32); //设置首行缩进
        paragraph.setLeading(30f); //行间距
        return paragraph;
    }

    /**
     * 添加段落 自动换行
     */
    public Paragraph createTextParagraph(String text) throws DocumentException {
        Paragraph paragraph = new Paragraph(text,paragraphFont);
        paragraph.setAlignment(0); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setIndentationLeft(12); //设置左缩进
        paragraph.setIndentationRight(12); //设置右缩进
        paragraph.setFirstLineIndent(32); //设置首行缩进
        paragraph.setLeading(30f); //行间距
        return paragraph;
    }

    /**
     * 创建段落 自动换行
     */
    public Paragraph createTextParagraph(String text,int alignment) {
        Paragraph paragraph = new Paragraph(text,paragraphFont);
        paragraph.setAlignment(alignment); //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setIndentationLeft(12); //设置左缩进
        paragraph.setIndentationRight(12); //设置右缩进
        paragraph.setFirstLineIndent(32); //设置首行缩进
        paragraph.setLeading(30f); //行间距
        return paragraph;
    }

    public void appendParagraph(Document document,Paragraph paragraph,String text) throws DocumentException {
        paragraph.add(text);
        document.add(paragraph);
    }

    /**
     * 添加下划线
     */
    public Paragraph addUnderLine(Paragraph paragraph,String text){
        if (StringUtils.isBlank(text)){
            text = shortSpacing;
        } else {
            text = StringUtils.join(" ",text," ");
        }
        Chunk sigUnderline = new Chunk(text);
        sigUnderline.setUnderline(0.1f, -2f);
        paragraph.add(sigUnderline);
        return paragraph;
    }

    /**
     * 添加下划线
     */
    public void addUnderLine(Document document,Paragraph paragraph,String text) throws DocumentException {
        if (StringUtils.isBlank(text)){
            text = shortSpacing;
        }
        Chunk sigUnderline = new Chunk(StringUtils.join(" ",text," "));
        sigUnderline.setUnderline(0.1f, -2f);
        paragraph.add(sigUnderline);
        document.add(paragraph);
    }

    /**objStmMark = null
     * 追加签名
     */
    public File mergePdf(String [] files,String savePath){
        PdfReader pdfReader = null;
        Document document = null;
        try {
            //创建一个与a.pdf相同纸张大小的document
            pdfReader = new PdfReader(files[0]);
            document = new Document(pdfReader.getPageSize(1));
            PdfCopy copy = new PdfCopy(document, new FileOutputStream(savePath));
            document.open();
            for (int i = 0; i < files.length; i++) {
                //一个一个的遍历现有的PDF
                PdfReader reader = new PdfReader(files[i]);
                int n = reader.getNumberOfPages();//PDF文件总共页数
                System.out.println("n:"+n);
                for (int j = 1; j <= n; j++) {
                    document.newPage();
                    PdfImportedPage page = copy.getImportedPage(reader, j);
                    copy.addPage(page);
                }
                reader.close();
            }
            document.close();
            pdfReader.close();
            return new File(savePath);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        } finally {
            document.close();
            pdfReader.close();
        }
        return null;
    }


    /**
     * 添加下划线
     */
    public Paragraph addUnderLine(Boolean check,Paragraph paragraph,String text1,String text2){
        Chunk sigUnderline = null;
        if (check){
            if (Objects.isNull(text1)){
                text1 = shortSpacing;
            } else {
                text1 = StringUtils.join(" ",text1," ");
            }
            sigUnderline = new Chunk(text1);
        } else {
            if (Objects.isNull(text2)){
                text2 = shortSpacing;
            } else {
                text2 = StringUtils.join(" ",text2," ");
            }
            sigUnderline = new Chunk(text2);
        }
        sigUnderline.setUnderline(0.1f, -2f);
        paragraph.add(sigUnderline);
        return paragraph;
    }

    /**
     * 添加下划线
     */
    public void addUnderLine(Document document,Boolean check,Paragraph paragraph,String text1,String text2) throws DocumentException {
        Chunk sigUnderline = null;
        if (check){
            if (Objects.isNull(text1)){
                text1 = shortSpacing;
            } else {
                text1 = StringUtils.join(" ",text1," ");
            }
            sigUnderline = new Chunk(text1);
        } else {
            if (Objects.isNull(text2)){
                text2 = shortSpacing;
            } else {
                text2 = StringUtils.join(" ",text2," ");
            }
            sigUnderline = new Chunk(text2);
        }

        sigUnderline.setUnderline(0.1F, -2.0F);
        paragraph.add(sigUnderline);
        document.add(paragraph);
    }

    /**
     * 添加下划线 Chunk
     */
    public Chunk createUnderLineChunk(String text) {
        if (Objects.isNull(text)){
            text = shortSpacing;
        } else {
            text = StringUtils.join(" ",text," ");
        }
        Chunk sigUnderline = new Chunk(text);
        sigUnderline.setUnderline(0.1f, -2f);
        return sigUnderline;
    }

    private Document createDocument() throws IOException {
        // 1.新建document对象 建立一个Document对象
        Document document = new Document(PageSize.A4);

        //
        PdfUtils.htFile.createNewFile();

        // 3.打开文档
        document.open();
        document.addTitle("销售合同");// 标题
        document.addAuthor("chuz");// 作者
        document.addSubject("Subject@iText pdf sample");// 主题
        document.addKeywords("Keywords@iTextpdf");// 关键字
        document.addCreator("chuz develop");// 创建者
        return document;
    }

    /**
     * 添加下划线 Chunk
     */
    public Chunk createUnderLineChunk(Boolean check,String text1,String text2) throws DocumentException {
        Chunk sigUnderline = null;
        if (check){
            if (Objects.isNull(text1)){
                text1 = shortSpacing;
            } else {
                text1 = StringUtils.join(" ",text1," ");
            }
            sigUnderline = new Chunk(text1);
        } else {
            if (Objects.isNull(text2)){
                text2 = shortSpacing;
            } else {
                text2 = StringUtils.join(" ",text2," ");
            }
            sigUnderline = new Chunk(text2);
        }

        sigUnderline.setUnderline(0.1f, -2f);
        return sigUnderline;
    }

    /**
     * 添加下划线 Chunk
     */
    public Chunk createChunk(String text) throws DocumentException {
        if (StringUtils.isBlank(text)){
            text = shortSpacing;
        }
        text = StringUtils.join(" ",text," ");
        return new Chunk(text);
    }

    /**
     * 添加带选择框文本
     */
//    public void addCheck(Document document,Boolean check,String text) throws Exception {
//        Paragraph paragraph = createTextParagraph("");
//        if (check){
//            paragraph.add(new Chunk(checkPng,0,0,true));
//        } else {
//            paragraph.add(new Chunk(unCheckPng,0,0,true));
//        }
//        Chunk chunk = new Chunk(StringUtils.join(" ",text),textfont);
//        paragraph.add(chunk);
//        document.add(paragraph);
//    }

    /**
     * 添加带选择框文本
     */
//    public void addCheck(Paragraph paragraph,Boolean check,String text) throws Exception {
//        if (check){
//            paragraph.add(new Chunk(checkPng,0,0,true));
//        } else {
//            paragraph.add(new Chunk(unCheckPng,0,0,true));
//        }
//        Chunk chunk = new Chunk(StringUtils.join(" ",text),textfont);
//        paragraph.add(chunk);
//    }

    /**
     * 添加带选择框文本
     */
//    public Paragraph addCheck(Boolean check,String text) throws Exception {
//        Paragraph paragraph = createTextParagraph("");
//        if (check){
//            paragraph.add(new Chunk(checkPng,0,0,true));
//        } else {
//            paragraph.add(new Chunk(unCheckPng,0,0,true));
//        }
//        Chunk chunk = new Chunk(StringUtils.join(" ",text),textfont);
//        paragraph.add(chunk);
//        return paragraph;
//    }

    /**
     * 添加带选择框文本
     */
//    public Paragraph appendCheck(Paragraph paragraph,Boolean check,String text) throws Exception {
//        if (check){
//            paragraph.add(new Chunk(checkPng,0,0,true));
//        } else {
//            paragraph.add(new Chunk(unCheckPng,0,0,true));
//        }
//        Chunk chunk = new Chunk(StringUtils.join(" ",text),textfont);
//        paragraph.add(chunk);
//        return paragraph;
//    }

    public void packageDateParagraph(Document document, Paragraph paragraph, Date date) throws DocumentException {
        if (Objects.nonNull(date)){
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);

            int year = calendar.get(Calendar.YEAR);
            int month = calendar.get(Calendar.MONTH) + 1;
            int day = calendar.get(Calendar.DAY_OF_MONTH);

            addUnderLine(paragraph,StringUtils.join(year));
            paragraph.add("年");
            addUnderLine(paragraph,StringUtils.join(month));
            paragraph.add("月");
            addUnderLine(paragraph,StringUtils.join(day));
            paragraph.add("日");
        } else {
            addUnderLine(paragraph,StringUtils.join(shortSlash));
            paragraph.add("年");
            addUnderLine(paragraph,StringUtils.join(shortSlash));
            paragraph.add("月");
            addUnderLine(paragraph,StringUtils.join(shortSlash));
            paragraph.add("日");
        }
        document.add(paragraph);
    }

    public MultipartFile fileToMultipartFile(File file) {
        FileItem fileItem = createFileItem(file);
        MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
        return multipartFile;
    }

    public static FileItem createFileItem(File file) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item = factory.createItem("textField", "text/plain", true, file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return item;
    }

    public String precision(BigDecimal number){
        if (Objects.nonNull(number)){
            return number.setScale(0,BigDecimal.ROUND_DOWN).toString();
        }
        return null;
    }
}

总结

解决每一个bug,开发每一个功能都是对程序员能力上、心里上的修炼。既然翻不过浪浪山,那就要适应浪浪山。
加油 希望我们都能变成最好的自己。
sunshine
2023年04月13日

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐