JAVA实现纯代码导出PDF文件

突发奇想,发布一篇生成pdf的博客。最初做导出pdf文件还是刚接触项目的时候,从最边缘的功能开始..........

想要实现导出PDF文件,但是当时已经生成了对应的Word文件,就想着直接把Word文件转为PDF就好了,还方便格式什么的都实现了,最后花了很大力气是实现了,但是效果不尽人意,就想着要不然直接生成PDF得了,后续就是看了一些博客,仿照着实现了导出PDF文件,但是自己最终实现效果有一点小瑕疵,一直没有空去有哈一下,最近有点空闲时间查了一下资料,把这个小瑕疵修复掉了。

好了....到此上效果图:

(1)这是正常情况:

(2)这是特殊情况

会出现第二种情况是因为一旦第二行的数据太多,第一页放不下的时候,就会强制分页。

其实在table对象上设置一个属性就好:

// 这个方法可以告诉iText在遇到需要分页的情况时,不要延迟分页,而是立即分页。这样可以避免表格的一部分内容被拆分到两页之间。
table2.setSplitLate(false);

接下来最主要的代码部分

1.首先是导入依赖

<dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.10</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
 </dependency>

2.下载接口

@GetMapping("/download")
    public void download(HttpServletResponse response, HttpServletRequest request) throws UnsupportedEncodingException {
        // 防止日志记录获取session异常
        request.getSession();
        // 设置编码格式
        response.setContentType("application/pdf;charset=UTF-8");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("下载的PDF名称", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".pdf");
        download1(response);
    }

3.下载方法实现

public void download1(HttpServletResponse response) {

        //要下载的数据查询数据部分我去掉了有需要自己根据业务取
        ArrayList<Map<String, Object>> list = new ArrayList<>();
        HashMap<String, Object> resultMap = new HashMap<>();

        HashMap<String, Object> resultMap1 = new HashMap<>();
        resultMap1.put("xm", "002");
        resultMap1.put("zw", "李四");
        resultMap1.put("zyzg","男");
        resultMap1.put("stzk", "2001-12-36");
        resultMap1.put("xyrwfg", "150269200110292012");
        resultMap1.put("sfwb", "18722061569");
        list.add(resultMap1);

        // 测试数据---实际将数据换为业务数据就ok
        HashMap<String, Object> resultMap2 = new HashMap<>();
        resultMap2.put("xm", "001");
        resultMap2.put("zw", "张三");
        resultMap2.put("zyzg", "在一片宁静的山谷之中,有一座古老的小镇,镇上的人们过着与世无争的生活。每当春天来临,山谷里的桃花便会竞相开放,将整个小镇装扮得如同仙境一般。小镇的居民们会在这个时候举行盛大的花节,庆祝春天的到来。孩子们穿着节日的盛装,在花丛中嬉戏;老人们则坐在树下,享受着温暖的阳光,讲述着过去的故事。这里的每一砖一瓦,每一草一木,都承载着岁月的记忆,让人感受到一种悠然自得的生活态度。随着时间的流逝,虽然外界的世界日新月异,但这座小镇依旧保持着它独有的宁静与美好,成为了一个远离喧嚣的理想之地。在一片宁静的山谷之中,有一座古老的小镇,镇上的人们过着与世无争的生活。每当春天来临,山谷里的桃花便会竞相开放,将整个小镇装扮得如同仙境一般。小镇的居民们会在这个时候举行盛大的花节,庆祝春天的到来。孩子们穿着节日的盛装,在花丛中嬉戏;老人们则坐在树下,享受着温暖的阳光,讲述着过去的故事。这里的每一砖一瓦,每一草一木,都承载着岁月的记忆,让人感受到一种悠然自得的生活态度。随着时间的流逝,虽然外界的世界日新月异,但这座小镇依旧保持着它独有的宁静与美好,成为了一个远离喧嚣的理想之地。");
        resultMap2.put("stzk", "2000-01-01");
        resultMap2.put("xyrwfg", "185214563257994512");
        resultMap2.put("sfwb", "13546235689");
        list.add(resultMap2);

        resultMap.put("xm", "006");
        resultMap.put("zw", "老六");
        resultMap.put("zyzg","男");
        resultMap.put("stzk", "2003-01-09");
        resultMap.put("xyrwfg", "120229186902101236");
        resultMap.put("sfwb", "15935262569");
        list.add(resultMap);

        // 定义全局的字体静态变量
        Font content = null;
        BaseFont bf;
        
        try {
            // 不同字体(这里定义为同一种字体:包含不同字号、不同style)
            BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            content = new Font(bfChinese, 10, Font.NORMAL);
            //创建字体
            bf = BaseFont.createFont( "STSong-Light", "UniGB-UCS2-H",
                    BaseFont.NOT_EMBEDDED);
            
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 创建文档对象
        Document document = new Document(new RectangleReadOnly(842F, 595F));
        //设置页边距  60:左边距,60:右边距,72:上边距,72:下边距
        document.setMargins(60, 60, 72, 72);

        try {
            PdfWriter writer = PdfWriter.getInstance(document,response.getOutputStream());
            //添加页码
            //添加页码
            PdfHeaderFooterEvent event = new PdfHeaderFooterEvent();
            writer.setPageEvent(event);
            //打开生成的pdf文件
            document.open();

            PdfPCell cell = null;

            // 设置表格的列宽和列数
            float[] widths2 = {25f,25f,25f,25f,25f,25f};
            PdfPTable table2 = new PdfPTable(widths2);
            table2.setSpacingBefore(20f);
            // 设置表格宽度为100%
            table2.setWidthPercentage(100.0F);
            table2.setHeaderRows(1);
            table2.getDefaultCell().setHorizontalAlignment(1);

            // 创建表头  content: 字体
            tableHeader(content, table2);

            // 填充内容
            setContentData(list, content, table2);

            document.add(new Paragraph("\n"));
            document.add(new Paragraph("▋ 基本信息",content));
            document.add(new Paragraph("\n"));
            // 设置分页策略
            table2.setSplitLate(false);
            document.add(table2);
            //关闭文档
            document.close();


        } catch (DocumentException | IOException e) {
            e.printStackTrace();

        }

    }

设置表头信息:

private static void tableHeader(Font content, PdfPTable table2) {
        PdfPCell cell;
        cell = new PdfPCell(new Paragraph("学号", content));
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setFixedHeight(20);
        table2.addCell(cell);

        cell = new PdfPCell(new Paragraph("姓名", content));
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        table2.addCell(cell);

        cell = new PdfPCell(new Paragraph("性别", content));
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        table2.addCell(cell);

        cell = new PdfPCell(new Paragraph("出生日期", content));
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        table2.addCell(cell);

        cell = new PdfPCell(new Paragraph("身份证号码", content));
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        table2.addCell(cell);

        cell = new PdfPCell(new Paragraph("联系电话", content));
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        table2.addCell(cell);
    }

填充表中数据:

private static void setContentData(ArrayList<Map<String, Object>> list, Font content, PdfPTable table2) {
        if(list.size() > 0){
            for (Map<String, Object> map : list) {
                PdfPCell cell1 = new PdfPCell(new Paragraph(map.get("xm").toString(), content));
                PdfPCell cell2 = new PdfPCell(new Paragraph(map.get("zw").toString(), content));
                PdfPCell cell3 = new PdfPCell(new Paragraph(map.get("zyzg").toString(), content));
                PdfPCell cell4 = new PdfPCell(new Paragraph(map.get("stzk").toString(), content));
                PdfPCell cell5 = new PdfPCell(new Paragraph(map.get("xyrwfg").toString(), content));
                PdfPCell cell6 = new PdfPCell(new Paragraph(map.get("sfwb").toString(), content));

                //单元格对齐方式
                cell1.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
                cell1.setFixedHeight(20);
                //单元格垂直对齐方式
                cell2.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell2.setVerticalAlignment(Element.ALIGN_MIDDLE);

                cell3.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell3.setVerticalAlignment(Element.ALIGN_MIDDLE);

                cell4.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell4.setVerticalAlignment(Element.ALIGN_MIDDLE);

                cell5.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell5.setVerticalAlignment(Element.ALIGN_MIDDLE);

                cell6.setHorizontalAlignment(Element.ALIGN_CENTER);
                cell6.setVerticalAlignment(Element.ALIGN_MIDDLE);

                table2.addCell(cell1);
                table2.addCell(cell2);
                table2.addCell(cell3);
                table2.addCell(cell4);
                table2.addCell(cell5);
                table2.addCell(cell6);
            }
        }
    }

补一下添加页码:

package com.hkr.plan.utils;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;

@Slf4j
public class PdfHeaderFooterEvent extends PdfPageEventHelper {

    /**
     * 重写页面结束时间  分别添加页眉、页脚
     */
    @Override
    public void onEndPage(PdfWriter writer, Document docment){
        try{
            this.addPageFooter(writer, docment);
        }catch(Exception e){
            log.error("添加页脚出错", e);
        }
    }

    /*
    /**
     * 页脚
     */
    private void addPageFooter(PdfWriter writer, Document docment){
        try {
            //创建字体
            BaseFont fs = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            Font font = new Font(fs, 10);
            Phrase pageNumberPh = new Phrase("- " + writer.getPageNumber() + " -",font);
            float center = writer.getPageSize().getRight()/2;
            float bottom = writer.getPageSize().getBottom() + 10;
            ColumnText.showTextAligned(writer.getDirectContent(),Element.ALIGN_CENTER,pageNumberPh,center,bottom,0);
        }catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

}

参考博客:java导出pdf(纯代码实现)-CSDN博客

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值