java使用itext自定义文档内容样式创建pdf文件,不使用pdf文件模板

一、背景

由于业务需求,我需要将程序的部分数据生成PDF报告以供下载浏览,且部分表单框样式希望根据内容的长短变化大小

二、实现方式

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) {
    
    

    }


三、效果图

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43288999/article/details/127747206