itextPdf工具类使用纪实-01

2023-03-01 13:40:36 浏览数 (1)

itextpdf工具类的使用

1、概述

需求:将数据库中的一些表格信息导出并存入pdf文件。于是乎接触到了itextpdf工具类,帮助我们更好的编排内容显示的位置和文件的导出。

2、工具类生成pdf文件样式图

页面的红色字体为截图工具的标准,不是代码生成的文字哦。 *如果您感觉符合您的需求,建议您在gitee下载源码,帮助您更快的实现您想要的效果。 源码地址

3、部分代码流程讲解

3.1、步骤一:引入依赖

代码语言:javascript复制
<!-- itextPdf start -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.4.3</version>
        </dependency>
        <!-- end -->

3.2、步骤二:创建文本对象和文件输出地址

代码语言:javascript复制
// 定义全局的字体静态变量
    private static Font titlefont;
    private static Font keyfont;
    private static Font textfont;

    // 静态代码块
    static {
        try {
            // 不同字体(这里定义为同一种字体:包含不同字号、不同style)
            BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            titlefont = new Font(bfChinese, 16, 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 FileNotFoundException, DocumentException {
        //1、创建Document对象,页面默认为A4格式,页面边框默认为30磅
        Document document = new Document(PageSize.A4);
        //2、设置文件输出路径
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("D:/text.pdf"));
        //3、设置pdf页眉和页脚和水印
        MyHeaderFooter headerFooter = new MyHeaderFooter();
        writer.setPageEvent(headerFooter);
        //4、给pdf填充内容
        document.open();

        //4.1、第一行:填入二维码和条形码
        PdfPTable header = createTable(new float[] {260, 260});
        header.addCell(createQrCode());
        header.addCell(createBarcode(writer));
        //设置当前table距离下方table内容的间距
        header.setSpacingAfter(10);
        document.add(header);

        //4.2、添加标题
        PdfPTable title = createTable(new float[] {120, 200, 200});
        title.addCell(createCell("员工列表信息", titlefont, Element.ALIGN_LEFT, 1, 3, false));
        //表头
        title.addCell(createCell("员工ID", keyfont, Element.ALIGN_CENTER, 1, 1, true));
        title.addCell(createCell("员工名称", keyfont, Element.ALIGN_CENTER, 1, 1, true));
        title.addCell(createCell("员工职称", keyfont, Element.ALIGN_CENTER, 1, 1, true));
        //内容
        title.addCell(createCell("1001", textfont, Element.ALIGN_CENTER, 1, 1, true));
        title.addCell(createCell("张三", textfont, Element.ALIGN_CENTER, 1, 1, true));
        title.addCell(createCell("初级工程师", textfont, Element.ALIGN_CENTER, 1, 1, true));
        title.addCell(createCell("1002", textfont, Element.ALIGN_CENTER, 1, 1, true));
        title.addCell(createCell("李四", textfont, Element.ALIGN_CENTER, 1, 1, true));
        title.addCell(createCell("中级工程师", textfont, Element.ALIGN_CENTER, 1, 1, true));
        title.setSpacingAfter(10);
        document.add(title);

        //4.3 实线分割
        // 直线
        Paragraph p1 = new Paragraph();
        p1.add(new Chunk(new LineSeparator()));
        p1.setSpacingAfter(40f);
        document.add(p1);
        // 虚线-分割线
        Paragraph p2 = new Paragraph();
        for (int i = 0; i < 71; i  ) {
            Chunk chunk = new Chunk("- ");
            p2.add(chunk);
        }
        p2.setSpacingAfter(40);
        document.add(p2);

        //4.4、列合并 --员工职称列合并
        PdfPTable colContent = createTable(new float[] {120, 200, 200});
        colContent.addCell(createCell("员工列表信息", titlefont, Element.ALIGN_LEFT, 1, 3, false));
        colContent.addCell(createCell("员工ID", keyfont, Element.ALIGN_CENTER, 1, 1, true));
        colContent.addCell(createCell("员工名称", keyfont, Element.ALIGN_CENTER, 1, 1, true));
        colContent.addCell(createCell("员工职称", keyfont, Element.ALIGN_CENTER, 1, 1, true));
        //内容
        colContent.addCell(createCell("1001", textfont, Element.ALIGN_CENTER, 1, 1, true));
        colContent.addCell(createCell("张三", textfont, Element.ALIGN_CENTER, 1, 1, true));
        colContent.addCell(createCell("初级工程师", textfont, Element.ALIGN_CENTER, 2, 1, true));
        colContent.addCell(createCell("1002", textfont, Element.ALIGN_CENTER, 1, 1, true));
        colContent.addCell(createCell("李四", textfont, Element.ALIGN_CENTER, 1, 1, true));
        colContent.setSpacingAfter(10);
        document.add(colContent);

        //4.5、行合并 -员工列表信息行合并
        PdfPTable rowContent = createTable(new float[] {120, 200, 200});
        rowContent.addCell(createCell("员工列表信息", titlefont, Element.ALIGN_LEFT, 1, 3, true));
        //表头
        rowContent.addCell(createCell("员工ID", keyfont, Element.ALIGN_CENTER, 1, 1, true));
        rowContent.addCell(createCell("员工名称", keyfont, Element.ALIGN_CENTER, 1, 1, true));
        rowContent.addCell(createCell("员工职称", keyfont, Element.ALIGN_CENTER, 1, 1, true));
        //内容
        rowContent.addCell(createCell("1001", textfont, Element.ALIGN_CENTER, 1, 1, true));
        rowContent.addCell(createCell("张三", textfont, Element.ALIGN_CENTER, 1, 1, true));
        rowContent.addCell(createCell("初级工程师", textfont, Element.ALIGN_CENTER, 1, 1, true));
        rowContent.addCell(createCell("1002", textfont, Element.ALIGN_CENTER, 1, 1, true));
        rowContent.addCell(createCell("李四", textfont, Element.ALIGN_CENTER, 1, 1, true));
        rowContent.addCell(createCell("中级工程师", textfont, Element.ALIGN_CENTER, 1, 1, true));
        rowContent.setSpacingAfter(10);
        document.add(rowContent);

        //结束关闭对象
        document.close();
    }

3.3、步骤三:封装生成表格对象方法

代码语言:javascript复制
/**
     * 创建指定列宽、列数的表格
     * @param widths 创建表单并设置初始的一行中每一个表格的长度
     * @return table对象
     */
    public static PdfPTable createTable(float[] widths) {
        PdfPTable table = new PdfPTable(widths);
        try {
            // 最大宽度
            int maxWidth = 520;
            table.setTotalWidth(maxWidth);
            table.setLockedWidth(true);
            table.setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getDefaultCell().setBorder(1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return table;
    }

3.4、步骤四:封装生成单元格对象方法

代码语言:javascript复制
/**
     * 创建单元格(指定字体、水平居..、单元格跨x列合并、设置单元格内边距)
     * @param value 内容
     * @param font 字体格式
     * @param align 内容位置
     * @param rowspan 行合并数
     * @param colspan 列合并数
     * @param boderFlag 边框是否显示
     * @return cell对象
     */
    public static PdfPCell createCell(String value, Font font, int align, int rowspan, int colspan, boolean boderFlag) {
        PdfPCell cell = new PdfPCell();
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(align);
        //行列合并数
        cell.setRowspan(rowspan);
        cell.setColspan(colspan);
        cell.setPhrase(new Phrase(value, font));
        cell.setPadding(3.0f);
        //是否显示边框
        if (!boderFlag) {
            cell.setBorder(0);
            cell.setPadding(5.0f);
        } else {
            //设置表格内容距离变宽的位置
            cell.setPadding(5.0f);
        }
        return cell;
    }

3.5、步骤五:生成二维码

代码语言:javascript复制
/**
     * 生成二维码
     */
    public static PdfPCell createQrCode(){
        PdfPCell cell = new PdfPCell();
        //1、绘制二维码
        BarcodeQRCode code = new BarcodeQRCode("这是二维码", 500, 500, null);
        try {
            //生成二维码图片,并设置绝对值大小
            Image image = code.getImage();
            image.setAbsolutePosition(50, 50);
            //2、生成二维码图像
            cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            //cell.setPadding(2);
            cell.setImage(image);
        } catch (BadElementException e) {
            e.printStackTrace();
        }
        return cell;
    }

3.6、步骤六:生成条形码

代码语言:javascript复制
public static PdfPCell createBarcode(PdfWriter writer){
        PdfPCell cell = new PdfPCell();
        //1、绘制条形码
        Barcode128 code = new Barcode128();
        //2、字号,条码高度,条码和数字间距
        code.setSize(6);
        code.setBarHeight(35);
        code.setBaseline(5);
        //3、条形码值
        code.setCode("123456789");
        cell.setPadding(2);
        cell.setImage(code.createImageWithBarcode(writer.getDirectContent(), null, null));
        return cell;
    }

3.7、步骤七:实现生成pdf页面事件监听

代码语言:javascript复制
/**
 * 继承 PdfPageEventHelper 实现生成pdf页面事件监听
 * 功能一:页眉和页脚
 * 功能二:页面水印设置
 */
class MyHeaderFooter extends PdfPageEventHelper{
    // 总页数 -默认体制
    PdfTemplate totalPage;
    Font hfFont;
    //static代码块优先于代码块执行
    {
        try {
            hfFont = new Font(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 8, Font.BOLD);
        } catch (DocumentException | IOException e) {
            e.printStackTrace();
        }
    }

    // 打开文档时,创建一个总页数的模版
    @Override
    public void onOpenDocument(PdfWriter writer, Document document) {
        PdfContentByte cb =writer.getDirectContent();
        totalPage = cb.createTemplate(30, 16);
    }

    // 一页加载完成触发,写入页眉和页脚
    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        PdfPTable table = new PdfPTable(2);
        try {
            //1、设置header的长度
            table.setTotalWidth(PageSize.A4.getWidth() - 75);
            table.setWidths(new int[] { 25, 25});
            table.setLockedWidth(true);
            table.getDefaultCell().setFixedHeight(-10);

            // 总页数
            PdfPCell totalCell = new PdfPCell(Image.getInstance(totalPage));
            //去边框
            totalCell.setBorder(0);
            totalCell.setHorizontalAlignment(Element.ALIGN_LEFT);

            // 初始页
            PdfPCell cell = new PdfPCell();
            //去边框
            cell.setBorder(0);
            cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
            cell.setPhrase(new Phrase("第"   writer.getPageNumber()   "页/", hfFont));
            table.addCell(cell);
            table.addCell(totalCell);
            // 将页眉写到document中,位置可以指定,指定到下面就是页脚
            // xPost设置距离左边框距离 -页脚
            table.writeSelectedRows(0, -1, 30,20, writer.getDirectContent());
            //页眉
            table.writeSelectedRows(0, -1, 30,PageSize.A4.getHeight() - 20, writer.getDirectContent());
            //2、添加水印
            generateWaterMark(writer);
        } catch (Exception de) {
            throw new ExceptionConverter(de);
        }
    }

    // 全部完成后,将总页数的pdf模版写到指定位置
    @Override
    public void onCloseDocument(PdfWriter writer, Document document) {
        String text = "总"   (writer.getPageNumber()-1)   "页";
        ColumnText.showTextAligned(totalPage, Element.ALIGN_LEFT, new Paragraph(text,hfFont), 1, 6, 0);
    }

    /**
     * 生成pdf页面添加水印
     * @param writer pdf写入类
     */
    private static void generateWaterMark(PdfWriter writer){
        BaseFont bfChinese;
        try {
            bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            PdfContentByte under = writer.getDirectContentUnder();
            under.beginText();
            PdfGState gs = new PdfGState();
            gs.setFillOpacity(0.5f);
            under.setGState(gs);
            under.setLeading(0.5f);
            under.setColorFill(new BaseColor(255, 170, 0));
            under.setFontAndSize(bfChinese, 24);
            under.setTextMatrix(300, 600);
            under.showTextAligned(Element.ALIGN_CENTER, "你好,这是水印!", 300, 600, 315);
            under.endText();
        } catch (DocumentException | IOException e) {
            e.printStackTrace();
        }
    }
}

谢谢您的阅览,期待对您有所帮助。

0 人点赞