JAVA纯代码导出PDF文件实现方式

 更新时间:2025年01月02日 11:01:50   作者:桃花面包  
本文介绍了作者通过突发奇想发布了生成PDF的博客,最初,作者通过将Word文件转换为PDF文件实现导出PDF功能,但效果不尽如人意,后来,作者尝试直接生成PDF文件,并修复了生成PDF时出现的小瑕疵,通过导入依赖、下载接口和下载方法的实现

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);
            }
        }
    }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 使用Netty解决TCP粘包和拆包问题过程详解

    使用Netty解决TCP粘包和拆包问题过程详解

    这篇文章主要介绍了使用Netty解决TCP粘包和拆包问题过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • Java Integer如何获取第一位和最后一位,并截取

    Java Integer如何获取第一位和最后一位,并截取

    这篇文章主要介绍了Java Integer如何获取第一位和最后一位并截取,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • 浅谈mybatis 乐观锁实现,解决并发问题

    浅谈mybatis 乐观锁实现,解决并发问题

    这篇文章主要介绍了浅谈mybatis 乐观锁实现,解决并发问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • 完美解决request请求流只能读取一次的问题

    完美解决request请求流只能读取一次的问题

    这篇文章主要介绍了完美解决request请求流只能读取一次的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • Springboot结合Mybatis-Plus实现业务撤销回滚功能

    Springboot结合Mybatis-Plus实现业务撤销回滚功能

    本文介绍了如何在Springboot结合Mybatis-Plus实现业务撤销回滚功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-12-12
  • springboot乱码问题排查思路解析

    springboot乱码问题排查思路解析

    这篇文章主要为大家介绍了springboot乱码问题排查思路解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • java地理坐标系及投影间转换代码示例

    java地理坐标系及投影间转换代码示例

    在地图投影中,经常需要将坐标从不同的坐标系之间进行转换,下面这篇文章主要给大家介绍了关于java地理坐标系及投影间转换的相关资料,需要的朋友可以参考下
    2024-08-08
  • 详解Java中接口的定义与实例代码

    详解Java中接口的定义与实例代码

    这篇文章主要介绍了详解Java中接口的定义与实例代码的相关资料,需要的朋友可以参考下
    2017-03-03
  • Java中的接口知识汇总

    Java中的接口知识汇总

    本文给大家汇总介绍了在java中的接口知识,包括为什么要使用接口、什么是接口、抽象类和接口的区别、如何定义接口以及定义接口注意点,希望大家能够喜欢
    2016-04-04
  • SpringBoot整合MybatisPlus的基本应用详解

    SpringBoot整合MybatisPlus的基本应用详解

    MyBatis-Plus (简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为 简化开发、提高效率而生,本文将给大家介绍一下SpringBoot整合MybatisPlus的基本应用,需要的朋友可以参考下
    2024-05-05

最新评论