Java uses itext custom document content style to create pdf files without using pdf file templates

1. Background

Due to business needs, I need to generate PDF reports from some of the program data for download and browsing, and some form box styles are expected to change in size according to the length of the content

2. Implementation method

public class PdfUtil {
    
    


    private static List<String> nameList = new ArrayList<>();
    private static Font titlefont;
    private static Font titlefont1;
    private static Font headfont;
    private static Font keyfont;
    private static Font textfont;
    private static int maxWidth = 520;

    static {
    
    
        nameList.add("r_project_name");
        nameList.add("r_header");
        nameList.add("r_appraisal");
        nameList.add("i_name");
        nameList.add("i_person");
        nameList.add("i_result");
        nameList.add("i_status");
        try {
    
    
            // 不同字体(这里定义为同一种字体:包含不同字号、不同style)
            BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            titlefont = new Font(bfChinese, 17, Font.BOLD, BaseColor.GRAY);
            titlefont1 = new Font(bfChinese, 15, Font.BOLD);
            headfont = new Font(bfChinese, 12, Font.BOLD);
            keyfont = new Font(bfChinese, 10, Font.BOLD);
            textfont = new Font(bfChinese, 10, Font.NORMAL);

        } catch (Exception e) {
    
    
            e.printStackTrace();
        }

    }

    public static void main(String[] args) throws DocumentException, IOException {
    
    
        Map<String, String> reviewData = new HashMap<>();
        reviewData.put("r_project_name", "测试项目");
        reviewData.put("r_header", "张三");
        reviewData.put("r_appraisal", "李四");
        reviewData.put("r_image", "C:\\Pictures\\fail.png");
        reviewData.put("r_type", "通过");

        List<Map<String,String>> itemData = new ArrayList<>();
        for(int i = 0;i<3;i++){
    
    
            Map<String,String> map = new HashMap<>();
            map.put("i_type","类型"+i);
            map.put("i_name","名称"+i);
            map.put("i_status","状态"+i);
            map.put("i_standard","标准"+i);
            map.put("r_image","C:\\Pictures\\fail.png");
            map.put("i_person","张三"+i);
            map.put("i_result","结果"+i);
            itemData.add(map);
        }
        createReportPdf("C:\\Pictures\\fail.png","D:\\test.pdf",reviewData,itemData);

    }


    /**
     * @description: 自定义pdf样式创建pdf
     * @params: [templateFile pdf右上角插入的图片地址
     * outputFile 生成pdf文件的地址
     * reviewData 评审数据
     * itemData 科目数据
     */
    public static String createReportPdf(String templateFile, String outputFile, Map<String, String> reviewData, List<Map<String, String>> itemData) throws IOException, DocumentException {
    
    
        //创建文档
        Document document = new Document(PageSize.A4);
        //文件生成输出路径
        File file = new File(outputFile);
        //初始化
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
        //设置页眉页脚
        writer.setPageEvent(new MyHeaderFooter());
        //开启文档编辑
        document.open();
        //通过图片路径初始化Image
        Image image = Image.getInstance(templateFile);
        //设置向右对齐
        image.setAlignment(Element.ALIGN_RIGHT);
        //依照比例缩放图片
        image.scalePercent(50);
        //创建总评表单
        PdfPTable table = createTable1(new float[]{
    
    5, 3, 15, 5});
        table.addCell(createCell("项目名称", headfont));
        table.addCell(createCell("专家", headfont));
        table.addCell(createCell("风险", headfont));
        table.addCell(createCell(reviewData.get("r_type"), headfont));
        table.addCell(createCell(reviewData.get("r_project_name"), textfont));
        table.addCell(createCell(reviewData.get("r_header"), textfont));
        table.addCell(createCell(reviewData.get("r_appraisal"), textfont));
        table.addCell(createImageCell(reviewData.get("r_image"), 1));
        //创建段落
        Paragraph paragraph = new Paragraph("评审情况", titlefont);
        //设置文字居中 0靠左   1,居中     2,靠右
        paragraph.setAlignment(0);
        //段落开头前距
        paragraph.setSpacingBefore(10f);
        //写入文档
        document.add(image);
        document.add(table);
        document.add(paragraph);
        createReportPdf(document, itemData);

        document.close();
        return outputFile;
    }

    /**
     * @description: 创建pdf中科目的样式
     * @params: [document, itemData]
     */
    public static void createReportPdf(Document document, List<Map<String, String>> itemData) throws IOException, DocumentException {
    
    

        for (Map<String, String> itemMap : itemData) {
    
    
            Paragraph paragraph = new Paragraph(itemMap.get("i_header"), titlefont1);
            document.add(paragraph);
            PdfPTable table = createTable(new float[]{
    
    10, 10, 10, 10, 10, 5});
            table.addCell(createCell("科目类型", keyfont));
            table.addCell(createCell(itemMap.get("i_type"), textfont));
            table.addCell(createCell("科目名称", keyfont));
            table.addCell(createCell(itemMap.get("i_name"), textfont));
            table.addCell(createCell("是否为必过", keyfont));
            table.addCell(createCell(itemMap.get("i_status"), textfont));
            table.addCell(createCell("标准值", keyfont, 6));
            table.addCell(createCell(itemMap.get("i_standard"), textfont, Element.ALIGN_LEFT, 6, 170f));
            table.addCell(createCell("评估结果", keyfont, 2));
            table.addCell(createImageCell(itemMap.get("r_image"), 4));
            table.addCell(createCell("评估人", keyfont, 2));
            table.addCell(createCell(itemMap.get("i_person"), textfont, 4));
            table.addCell(createCell("测试结果及风险评估", keyfont, 6));
            table.addCell(createCell(itemMap.get("i_result"), textfont, Element.ALIGN_LEFT, 6, 100f));
            document.add(table);
        }


        document.close();
    }


    /**
     * @description: 创建图片单元格
     * @params: [imagePath, colspan]
     */
    public static PdfPCell createImageCell(String imagePath, int colspan) throws BadElementException, IOException {
    
    

        if (imagePath == null || "".equals(imagePath)) {
    
    
            return new PdfPCell();
        }
        //通过图片路径初始化图片
        Image image = Image.getInstance(imagePath);
        //居中
        image.setAlignment(Element.ALIGN_CENTER);
        //按70的比例缩小
        image.scalePercent(70);
        //添加到单元格内
        PdfPCell pCell = new PdfPCell(image, false);
        //跨列
        pCell.setColspan(colspan);
        //设置居中
        pCell.setHorizontalAlignment(Element.ALIGN_CENTER);
        pCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        return pCell;

    }

    /**
     * @description: 创建单元格指定内容和字体
     * @params: [value, font]
     */
    public static PdfPCell createCell(String value, Font font) {
    
    

        PdfPCell cell = new PdfPCell();
        //居中
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        //设置最小高度
        cell.setMinimumHeight(30f);
        cell.setPhrase(new Phrase(value, font));
        return cell;
    }

    /**
     * @description: 创建单元格指定内容,字体,跨列
     * @params: [value, font, colspan]
     */
    public static PdfPCell createCell(String value, Font font, int colspan) {
    
    

        PdfPCell cell = new PdfPCell();
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setColspan(colspan);
        cell.setMinimumHeight(30f);
        cell.setPhrase(new Phrase(value, font));
        return cell;
    }

    /**
     * @description: 创建单元格指定 内容、字体、位置、跨列、最小高度
     * @params: [value, font, align, colspan, height]
     */
    public static PdfPCell createCell(String value, Font font, int align, int colspan, float height) {
    
    

        PdfPCell cell = new PdfPCell();
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(align);
        cell.setColspan(colspan);
        cell.setMinimumHeight(height);
        cell.setPhrase(new Phrase(value, font));
        return cell;
    }

    /**
     * @description: 创建表单指定列数
     * @params: [widths]
     */
    public static PdfPTable createTable1(float[] widths) {
    
    

        PdfPTable table = new PdfPTable(widths);
        try {
    
    
            table.setTotalWidth(maxWidth);
            table.setLockedWidth(true);
            table.setSpacingBefore(5.0f);

            table.setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getDefaultCell().setBorder(1);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return table;
    }

    public static PdfPTable createTable(float[] widths) {
    
    
        PdfPTable table = new PdfPTable(widths);
        try {
    
    
            //设置宽度
            table.setTotalWidth(maxWidth);
            //固定宽度
            table.setLockedWidth(true);
            //前距
            table.setSpacingBefore(15.0f);
            //后距
            table.setSpacingAfter(30.0f);
            //内容居中
            table.setHorizontalAlignment(Element.ALIGN_CENTER);
            //设置边框
            table.getDefaultCell().setBorder(1);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return table;
    }

}

class MyHeaderFooter extends PdfPageEventHelper {
    
    

    static Font hfFont;

    static {
    
    
        try {
    
    
            hfFont = new Font(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 12, Font.NORMAL);
        } catch (DocumentException | IOException e) {
    
    
            e.printStackTrace();
        }
    }


    @Override
    public void onOpenDocument(PdfWriter writer, Document document) {
    
    

    }


    /**
     * @description: 一页加载完成触发,写入页眉和页脚
     * @params: [writer, document]
     * @return:

     */
    @Override
    public void onEndPage(PdfWriter writer, Document document) {
    
    

        PdfPTable table = new PdfPTable(1);
        try {
    
    
            table.setTotalWidth(520);
            table.setWidths(new int[]{
    
    1});
            table.setLockedWidth(true);
            PdfPCell headerCell = new PdfPCell();
            headerCell.setPhrase(new Phrase("第" + writer.getPageNumber() + "页", hfFont));
            headerCell.setFixedHeight(30f);
            headerCell.setBorderWidthLeft(0);
            headerCell.setBorderWidthRight(0);
            headerCell.setBorderWidthTop(0);
            headerCell.setBorderWidthBottom(0);
            headerCell.setHorizontalAlignment(Element.ALIGN_CENTER);

            table.addCell(headerCell);
            // 将页眉写到document中
            table.writeSelectedRows(0, -1, 25, PageSize.A4.getBottom() + 30, writer.getDirectContent());
            PdfPTable headerTable = new PdfPTable(1);
            headerTable.setTotalWidth(520);
            //设置页眉内容
            PdfPCell footCell = new PdfPCell();
            footCell.setPhrase(new Phrase("测试报告", hfFont));
            footCell.setFixedHeight(25f);
            //设置单元格无边框
            footCell.setBorderWidthLeft(0);
            footCell.setBorderWidthRight(0);
            footCell.setBorderWidthTop(0);
            footCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
            headerTable.addCell(footCell);
            //页码写入
            headerTable.writeSelectedRows(0, -1, 37, PageSize.A4.getHeight() - 10, writer.getDirectContent());
        } catch (Exception de) {
    
    
            throw new ExceptionConverter(de);
        }
    }

    // 全部完成后,将总页数的pdf模版写到指定位置
    @Override
    public void onCloseDocument(PdfWriter writer, Document document) {
    
    

    }


3. Rendering

insert image description here
insert image description here

Guess you like

Origin blog.csdn.net/weixin_43288999/article/details/127747206