浅谈使用itext7制作pdf

itext7生成pdf经验之谈
最近在工作中需要使用itext7.1.11在后端生成pdf,由于官方文档不全,很多样式设置都需要自己多次尝试,折磨了我将近两周时间终于实现了产品要求样式特复杂的pdf。在此把我实现过程做一个总结。

一.pom.xml文件中加入jar依赖
1.配置itex7版本号

 <properties>
        <itext.version>7.1.11</itext.version>
 </properties>

2.配置相关jar包

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>kernel</artifactId>
    <version>${itext.version}</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>io</artifactId>
    <version>${itext.version}</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>layout</artifactId>
    <version>${itext.version}</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>forms</artifactId>
    <version>${itext.version}</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>pdfa</artifactId>
    <version>${itext.version}</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>pdftest</artifactId>
    <version>${itext.version}</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>font-asian</artifactId>
    <version>${itext.version}</version>
</dependency>

二.制作pdf实现过程
1.引入静态文件
在这里插入图片描述

2.获取字体
在这里插入图片描述
3.初始化pdf
在这里插入图片描述
4.设置页眉页脚监听事件,以及页码监听事件

/**
 * pdf页眉页脚监听事件
 * @author :iyb-gaozhiqi
 * @description :
 * @date :2021-08-30 16:49:00
 */
public class HeaderAndFooterHandler implements IEventHandler {
    /**
     * 页眉
     */
    private Image    headerImage;
    /**
     * 页脚
     */
    private Image    footerImage;
    /**
     * 文档
     */
    private Document doc;
    /**
     * 字体
     */
    private PdfFont  font;

    /**
     *监听事件
     * @param headerImage
     * @param footerImage
     */
    public HeaderAndFooterHandler(Image headerImage, Image footerImage, Document doc, PdfFont font) {
        this.footerImage = footerImage;
        this.headerImage = headerImage;
        this.doc = doc;
        this.font = font;

    }

    /**
     * 监听事件
     * @param event
     */
    @SneakyThrows
    @Override
    public void handleEvent(Event event) {
        PdfDocumentEvent documentEvent = (PdfDocumentEvent) event;
        PdfPage page = documentEvent.getPage();
        int pageNum = documentEvent.getDocument().getPageNumber(page);
        if (pageNum > 2) {
            //加页码
            headerImage.scaleAbsolute(620, 70);
            Paragraph header = new Paragraph();
            header.add(headerImage);

            footerImage.scaleToFit(622, 60);

            Paragraph footer = new Paragraph();
            footer.add(footerImage);

            Canvas canvas = new Canvas(documentEvent.getPage(), PageSize.A4);
            if (pageNum > 13) {
                canvas.setFont(font).showTextAligned(header, 295, PageSize.A4.getTop() - doc.getTopMargin() + 10,
                        TextAlignment.CENTER).showTextAligned(footer, 298, 0, TextAlignment.CENTER).close();
            }
        }
    }
}
/**
 * pdf页码监听事件
 * @author :iyb-gaozhiqi
 * @description :
 * @date :2021-08-30 16:49:00
 */
public class PdfPageHandler implements IEventHandler {
    /**
     * pdf文档
     */
    private PdfDocument pdf;
    /**
     * pdf字体
     */
    private PdfFont     font;
    /**
     * pdf样式
     */
    private Integer     pdfStyle;

    /**
     * 页码监听
     * @param pdf
     * @param font
     * @param pdfStyle
     */
    public PdfPageHandler(PdfDocument pdf, PdfFont font, Integer pdfStyle) {
        this.pdf = pdf;
        this.font = font;
        this.pdfStyle = pdfStyle;

    }

    /**
     * 监听事件
     * @param event
     */
    @SneakyThrows
    @Override
    public void handleEvent(Event event) {
        PdfDocumentEvent documentEvent = (PdfDocumentEvent) event;
        PdfPage page = documentEvent.getPage();
        int pageNum = documentEvent.getDocument().getPageNumber(page);
        Color color = null;
        if(Objects.equals(PdfStyleEnum.FINANCE.getType(),pdfStyle)){
            color = ServiceHelper.transColor("#965622");
        }else{
            color = ServiceHelper.transColor("#999999");
        }
        if (pageNum > 2) {
            Canvas canvas = new Canvas(documentEvent.getPage(), PageSize.A4);
            canvas.setFont(font).setFontColor(color)
                    .showTextAligned(String.valueOf(pdf.getNumberOfPages() - 3), 300, 30, TextAlignment.CENTER).close();
        }
    }
}

5.设置单元格方法

/**
     * 给单元格设置行列和文本
     * @param rowspan
     * @param colspan
     * @param text
     * @return
     */
    private Cell cell(int rowspan, int colspan, String text) {
        Cell cell = new Cell(rowspan, colspan);
        Border border = new SolidBorder(ServiceHelper.transColor("#cccccc"), 1);
        cell.setBorder(border);
        cell.setFont(font).setMinHeight(10).setTextAlignment(TextAlignment.CENTER)
                .setHorizontalAlignment(HorizontalAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE);
        Paragraph p = new Paragraph(text);
        p.setFixedLeading(17);
        cell.add(p);
        return cell;
    }

    /**
     * 给单元格设置文本
     * @param text
     * @return
     */
    private Cell cell(String text) {
        return cell(1, 1, text);
    }

    /**
     * 给单元格设置文本
     * @param paragraph
     * @return
     */
    private Cell cell(Paragraph paragraph) {
        return cell(1, 1, paragraph);
    }

    /**
     * 给单元格设置行列和文本
     * @param rowspan
     * @param colspan
     * @param paragraph
     * @return
     */
    private Cell cell(int rowspan, int colspan, Paragraph paragraph) {
        Cell cell = new Cell(rowspan, colspan);
        Border border = new SolidBorder(ServiceHelper.transColor("#cccccc"), 1);
        cell.setBorder(border);
        cell.setFont(font).setMinHeight(10).setTextAlignment(TextAlignment.CENTER)
                .setHorizontalAlignment(HorizontalAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE);
        paragraph.setFixedLeading(17);
        cell.add(paragraph);
        return cell;
    }

6.获取静态图片通用方法

/**
     * 获取图片文件
     * @param fileName
     * @return
     */
    private Image getImage(String fileName) {
        String pathPrefix = "brand/";
        Image image = new Image(
                ImageDataFactory.create(this.getClass().getClassLoader().getResource(pathPrefix + fileName)));
        return image;
    }

    /**
     * 获取字体
     * @param fileName
     * @return
     */
    private PdfFont getPdfFont(String fileName) throws IOException {
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("brand/" + fileName);
        PdfFont font = PdfFontFactory.createFont(IOUtils.toByteArray(in), PdfEncodings.IDENTITY_H, true); // 使用自定义字体
        return font;
    }

    /**
     * 获取图片文件,并设置大小
     * @param fileName
     * @return
     */
    private Image getArrowImage(String fileName) {
        String pathPrefix = "brand/";
        Image image = new Image(
                ImageDataFactory.create(this.getClass().getClassLoader().getResource(pathPrefix + fileName)));
        image.scaleAbsolute(20, 10);
        return image;
    }

7.设置表格内容

private void table(CreateReportPdfDto createReportPdfDto) {
        //换页
        doc.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
        Paragraph p1 = new Paragraph();
        p1.setHorizontalAlignment(HorizontalAlignment.LEFT);
        p1.setWidth(UnitValue.createPercentValue(100));
        p1.setHeight(UnitValue.createPercentValue(100));
        p1.setCharacterSpacing(0.4f); // 字间距
        p1.add(new Text("家庭风险保障额度总览\n").setFontColor(ServiceHelper.transColor("#009BD1")).setFontSize(28).setBold());
        p1.add(new Text("表格中呈现的保额数据仅对应此报告的生成时间,责任额度依照聚合规则分类汇总,无法囊括所有特殊责任。")
                .setFontColor(Color.convertRgbToCmyk(new DeviceRgb(51, 51, 51))).setFontSize(14));
        Color rgb = ServiceHelper.transColor("#009BD1");
        Color color = ServiceHelper.transColor("#FFFFFF");
        doc.add(p1);
        Div div = new Div();
        div.setPaddings(20, 0, 20, 0);
        java.util.List<SummaryDto> summaryList = createReportPdfDto.getSummaryList();
        for (int i = 0; i < summaryList.size(); i++) {
            SummaryDto summary = summaryList.get(i);
            String[] insuredArr = summary.getInsuredList();
            int insuredSize = insuredArr.length;

            float[] colWidths = new float[insuredSize + 2];
            colWidths[0] = 300;
            colWidths[1] = 300;

            float customHeaderWidth = (TABLE_WIDTH - 600) / insuredSize;
            for (int j = 0; j < insuredSize; j++) {
                colWidths[j + 2] = customHeaderWidth;
            }

            Table table = new Table(colWidths);
            table.setFont(font);
            table.setWidth(UnitValue.createPercentValue(100));
            Cell head_11 = cell(2, 1, "责任类别").setFontColor(color).setBackgroundColor(rgb);
            Cell head_12 = cell(2, 1, "责任细则").setFontColor(color).setBackgroundColor(rgb);
            Cell head_13 = cell(1, insuredSize, "保障额度").setFontColor(color).setBackgroundColor(rgb);
            table.addCell(head_11);
            table.addCell(head_12);
            table.addCell(head_13);

            for (int j = 0; j < insuredSize; j++) {
                Cell customHeaderCell = cell(insuredArr[j]).setFontColor(color).setBackgroundColor(rgb);
                table.addCell(customHeaderCell);
            }

            java.util.List<FamilyDutyTypeDto> tableList = summary.getTable();
            for (int j = 0; j < tableList.size(); j++) {
                FamilyDutyTypeDto tableData = tableList.get(j);
                java.util.List<DutyTypeDetailDto> subList = tableData.getSubList();
                int subSize = subList.size();

                Cell row_x1 = cell(subSize, 1, tableData.getMain());
                table.addCell(row_x1);

                for (int k = 0; k < subSize; k++) {
                    DutyTypeDetailDto sub = subList.get(k);
                    Cell row_x2 = cell(sub.getName());
                    table.addCell(row_x2);

                    String[] items = sub.getValues();
                    for (int m = 0; m < items.length; m++) {
                        Cell cell_xm = cell(items[m]);
                        table.addCell(cell_xm);
                    }
                }
            }
            div.add(table);
            if (i < summaryList.size() - 1) {
                Paragraph spaceP = new Paragraph();
                spaceP.setHeight(20);
                div.add(spaceP);
            }
        }
        //保障建议
        if(CollectionUtils.isNotEmpty(createReportPdfDto.getAdvices())){
            Paragraph p2 = new Paragraph();
            p2.setHorizontalAlignment(HorizontalAlignment.LEFT);
            p2.setWidth(UnitValue.createPercentValue(100));
            p2.setHeight(UnitValue.createPercentValue(100));
            p2.setCharacterSpacing(0.4f); // 字间距
            p2.add(new Text("保障建议\n").setFontColor(ServiceHelper.transColor("#009BD1")).setFontSize(20).setBold());
            div.add(p2);
            for(int k = 0;k<createReportPdfDto.getAdvices().size();k++){
                ReportAdviceDto reportAdviceDto = createReportPdfDto.getAdvices().get(k);
                Color rgb2 = ServiceHelper.transColor("#F5FDFF");
                float[] colWidths = {1};
                Table table = new Table(UnitValue.createPercentArray(colWidths));
                table.setWidth(526);
                table.setBackgroundColor(rgb2);
                table.setBorder(Border.NO_BORDER);
                Cell head_11 = cell(1, 1, reportAdviceDto.getApplicant()).setTextAlignment(TextAlignment.LEFT).setFontColor(ServiceHelper.transColor("#009BD1"));
                head_11.setBorder(Border.NO_BORDER);
                Cell head_12 = cell(1, 1, reportAdviceDto.getText()).setTextAlignment(TextAlignment.LEFT);
                head_12.setBorder(Border.NO_BORDER);
                table.addCell(head_11);
                table.addCell(head_12);
                div.add(table);
                if (k < createReportPdfDto.getAdvices().size() - 1) {
                    Paragraph spaceP = new Paragraph();
                    spaceP.setHeight(10);
                    div.add(spaceP);
                }
            }
        }
        doc.add(div);
    }

8.制作pdf返回文件流

/**
     *生成pdf
     * @param createReportPdfDto
     * @return
     */
    private String generatePdf(CreateReportPdfDto createReportPdfDto) {
        String result = "";
        ByteArrayOutputStream baos = null;
        try {
            baos = new ByteArrayOutputStream();//构建字节输出流
            //初始化pdf
            init(baos);
            Image headerImage = getImage("header.png");
            Image footerImage = getImage("footer.png");
            //增加页眉页脚监听事件
            HeaderAndFooterHandler headerAndFooterHandler = new HeaderAndFooterHandler(headerImage, footerImage, doc,
                    font);
            pdf.addEventHandler(PdfDocumentEvent.START_PAGE, headerAndFooterHandler);
            //加页码监听事件
            PdfPageHandler pdfPageHandler = new PdfPageHandler(pdf, font, createReportPdfDto.getPdfStyle());
            pdf.addEventHandler(PdfDocumentEvent.END_PAGE, pdfPageHandler);
            //pdf封面
            cover(createReportPdfDto);
            //目录
            content(createReportPdfDto.getContents());
            //平台介绍
            cover1();
            //合作公司
            cover2();
            //保通保险服务介绍
            cover3();
            //保通保险服务介绍-服务内容
            cover31();
            //保通保险服务介绍-家庭风险
            cover32();
            //保通保险服务介绍-企业风险
            cover33();
            //保通保险服务介绍-全能核
            cover34();
            //保通保险服务介绍-省心赔
            cover35();
            //保单托管服务价值
            cover4();
            //风险管理配置-人生七张保单
            cover5();
            //风险管理配置-家庭四大平衡账户
            cover6();
            //家庭年度保费总览
            familyOverview(createReportPdfDto);
            //年度保费清单
            getFamilyPremiumList(createReportPdfDto);
            //家庭年度保单/保费占比-投保人
            policyRateByApplicant(createReportPdfDto.getDynamicImages().getPieChartList());
            //家庭年度保单/保费占比-被保人
            policyRateByInsured(createReportPdfDto.getDynamicImages().getPieChartList());
            //保单交费查询
            policyPaymentInquiry(createReportPdfDto.getStatisticsDate(), createReportPdfDto.getTotalFee(),
                    createReportPdfDto.getPayRecordList());
            //家庭风险保障额度总览
            table(createReportPdfDto);
            //家庭保单管理
            familyPolicyManage(createReportPdfDto.getTotalPolicy(), createReportPdfDto.getPolicyList());
            //受益人
            getBeneficiaryData(createReportPdfDto.getBenefitList());
            //家庭财富风险顾问
            familyRisk(createReportPdfDto.getDynamicImages(), createReportPdfDto.getAgent(), headerAndFooterHandler);
            //封底
            endCover(pdfPageHandler);
            //关闭相关pdf
            closePdf();
            result = Base64Utils.encodeToString(baos.toByteArray());
        } catch (Exception e) {
            log.error("PDF异常", e);
        } finally {
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    log.error("PDF异常", e);
                }
            }
        }

        return result;
    }

9.关闭文档

/**
     * 关闭
     */
    private void closePdf() {
        if (null != doc) {
            doc.close();
        }
    }
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值