Java实现PDF导出/预览

news2024/11/20 4:57:22

        网上有很多关于PDF导出的文章,但是个人感觉实现的过于复杂,又是模板又是html的,有的还需要字体模板的支持,本片文章只是实现简单的PDF表格导出,可以实现PDF动态表格导出/预览,这类文章网上很少,就给你们整理一篇吧!

实现思路:本地创建PDF文件 --》打开PDF文件 --〉写入各种数据 --》保存PDF --〉 将PDF输出到页面下载 --》 删除本地PDF文件

第一步:导入相关的依赖,如果原来有依赖记得替换一下哦,免得版本不一致导致其他产生的各种问题。

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.5</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>

 第二步:创建所需要的实体类

package com.hyper.pdf;

import lombok.Data;

/**
 * 标题名称/内容设置实体类
 */
@Data
public class ProcessVo {
    /**
     * 序号
     */
    private String index;
    /**
     * 审核人
     */
    private String assignee;
    /**
     * 审核人名称
     */
    private String assigneeName;
    /**
     * 审核时间
     */
    private String verifyTime;
    /**
     * 审核结果
     */
    private String verifyResult;
    /**
     * 审核意见
     */
    private String verifyMessage;
}
package com.hyper.pdf;

import lombok.Data;

import java.util.List;

@Data
public class ProcessTaskVo {
    private  String taskName="审核人";
    private  String startUserName="审核发起人";
    private  String startTime="2022-03-04";
    /**
     * 导出的数据 processVoList
     */
    private List<ProcessVo> processVoList;
}

第三步:所有代码我都放到了控制层里面,各位自行开发细化,按照自己的要求调整即可。

package com.hyper.web;

import cn.hutool.core.bean.BeanUtil;
import com.amazonaws.util.IOUtils;
import com.hyper.pdf.ProcessTaskVo;
import com.hyper.pdf.ProcessVo;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/pdf")
public class HelloController {

    @GetMapping("/pdf")
    public void processPdfSample(HttpServletRequest request, HttpServletResponse response) {
        ProcessTaskVo processTaskVo = new ProcessTaskVo();
        // 扩大指针作用域
        Document document = null;
        ByteArrayOutputStream fileOut = new ByteArrayOutputStream();
        OutputStream responseOutputStream = null;
        try {
            // 导出PDF文件名称
            final String pdfDocName = "周报" + ".pdf";
            // 系统路径
            File file = new File(pdfDocName);
            file.createNewFile();
            //1:建立Document对象实例
            document = new Document();
            StringBuilder filename = new StringBuilder();
            //PDF标题
            String pdfName = "测试导出的PDF";
            filename.append(pdfName).append(new SimpleDateFormat("yyyyMMddHHmm").format(new
                    Date()));
            document.addAuthor("Author@SALES");
            document.addCreationDate();
            document.addCreator("Creator@SALES");
            document.setMargins(10, 10, 10, 10);

            PdfWriter pdfWriter = PdfWriter.getInstance(document, fileOut);
            pdfWriter.setPdfVersion(PdfWriter.VERSION_1_4);
            // 3:打开文档
            document.open();

            //解决中文不显示问题
            BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            Font fontChina14 = new Font(bfChinese, 14);
            Font fontChina12 = new Font(bfChinese, 12);

            // 4:向文档添加内容
            Paragraph titleParagraph = new Paragraph(pdfName, fontChina14);
            // 居中
            titleParagraph.setAlignment(Element.ALIGN_CENTER);
            document.add(titleParagraph);
            // 空格
            Paragraph blank1 = new Paragraph(" ");
            document.add(blank1);
            // 表格处理及查询数据
            java.util.List<ProcessVo> processVoLists = new ArrayList<>();
            for (int i = 0; i < 30; i++) {
                ProcessVo processVo1 = new ProcessVo();
                processVo1.setIndex(i+"");
                processVo1.setAssignee("李四");
                processVo1.setAssigneeName("张三");
                processVo1.setVerifyTime("2022-03-04");
                processVo1.setVerifyResult("通过");
                processVoLists.add(processVo1);
            }

            processTaskVo.setProcessVoList(processVoLists);
            PdfPTable table = packageTable(processTaskVo, fontChina12);
            if (null != table) {
                document.add(table);
            }
            // 5:关闭文档
            document.close();
            //注释可在线预览
            witerFile(request, response, file, false);
            responseOutputStream = response.getOutputStream();
            fileOut.writeTo(responseOutputStream);
            responseOutputStream.close();
            //删除文件
            file.delete();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileOut.close();
                responseOutputStream.close();
            } catch (IOException exception) {
                System.out.printf("下载异常");
            }
        }
    }

    /**
     * 写出文件
     *
     * @param request
     * @param response
     * @param file
     * @param deleteOnExit
     */
    private void witerFile(HttpServletRequest request, HttpServletResponse response, File file, boolean deleteOnExit) {
        response.setCharacterEncoding(request.getCharacterEncoding());
        response.setContentType("application/pdf");
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            //这里主要防止下载的PDF文件名乱码
            String fileName = URLEncoder.encode(file.getName(), "UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            IOUtils.copy(fis, response.getOutputStream());
            response.flushBuffer();
        } catch (Exception e) {
            System.out.printf("下载异常111");
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                    if (deleteOnExit) {
                        file.deleteOnExit();
                    }
                } catch (IOException e) {
                    System.out.printf("下载异常222");
                }
            }
        }
    }

    public static PdfPTable packageTable(ProcessTaskVo processTaskVo, Font fontZH) {
        try {
            // 创建table下面通过table.addCell添加的时候必须添加整行内容的所有列
            PdfPTable table = new PdfPTable(6);
            table.setWidthPercentage(100.0F);
            //第一行是列表名
            table.setHeaderRows(1);
            table.getDefaultCell().setHorizontalAlignment(1);
            java.util.List<ProcessVo> processVoList = processTaskVo.getProcessVoList();

            if (null != processVoList && processVoList.size() > 0) {
                List<ProcessVo> newProcessVoList = new ArrayList<>();
                ProcessVo processVo = new ProcessVo();
                processVo.setIndex("数据1");
                processVo.setAssignee("审批人2");
                processVo.setAssigneeName("审批人姓名3");
                processVo.setVerifyTime("审批时间");
                processVo.setVerifyResult("审批结果");
                processVo.setVerifyMessage("审批意见");
                newProcessVoList.add(processVo);

                for (ProcessVo tableProcessVo : processVoList) {
                    ProcessVo newProcessVo = new ProcessVo();
                    BeanUtil.copyProperties(tableProcessVo, newProcessVo);
                    newProcessVoList.add(newProcessVo);
                }
                //遍历List 获取每一列的数据,填充到pdfTable中
                newProcessVoList.forEach(vo -> {
                    table.addCell(createCell(vo.getIndex(), fontZH));
                    table.addCell(createCell(vo.getAssignee(), fontZH));
                    table.addCell(createCell(vo.getAssigneeName(), fontZH));
                    table.addCell(createCell(vo.getVerifyTime(), fontZH));
                    table.addCell(createCell(vo.getVerifyResult(), fontZH));
                    table.addCell(createCell(vo.getVerifyMessage(), fontZH));
                });
            }
            //cell跨页
            table.setKeepTogether(false);
            table.setSplitLate(false);
            table.setSplitRows(true);
            return table;
        } catch (Exception e) {
            return null;
        }
    }
    private static PdfPCell createCell(String value, Font fontZH) {
        PdfPCell cell = new PdfPCell();
        cell.setPhrase(new Phrase(value, fontZH));
        cell.setColspan(1);
        cell.setUseAscender(true);
        cell.setUseDescender(true);
        //水平居中
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        //垂直居中
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        return cell;
    }
}

最后实现的效果如下,可以实现预览后下载的,具体的话看代码备注,上面代码应该是全的,如果发现有漏掉的代码或者依赖可以留言作者,定会第一时间完善的。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/541245.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实践「容器镜像扫描」,Get 云原生应用的正确打开方式

&#x1f31f; 容器技术的兴起&#xff0c;让应用程序更加轻量化和可移植&#xff0c;大大提高了应用交付效率。但容器中的应用也面临各种安全威胁&#xff0c;容器及其镜像安全不可小觑。 近日&#xff0c;在「DevSecOps 软件安全开发实践」课程上&#xff0c;极狐(GitLab) 高…

Linux设置系统时间(上海时区、硬件时间、重启有效)

#查看时间 date#删除当前时区 rm -rf /etc/localtime #修改默认时区为上海 ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime #设置硬件时间 月/日/年 时:分:秒 hwclock --set --date"05/18/2023 17:11:15"#设置系统时间和硬件时间同步 hwclock --hctosys#保…

大数据发展前沿复习

对抗学习 生成对抗网络&#xff08;GAN&#xff09;是非监督式学习的一种方法&#xff0c;透过两个神经网络相互博弈的方式进行学习。生成对抗网络由一个生成网络与一个判别网络组成。生成网络以随机取样作为输入&#xff0c;其输出结果需要尽量模仿训练集中的真实样本。判别网…

vmware17pro安装激活ubuntu22版本最新教程无废话

第一步&#xff1a;下载 下载很方便 官方一键下载链接 第二步 安装 点下一步&#xff0c;一键安装即可&#xff0c;有可能会重启电脑&#xff0c;没关系的&#xff0c;是安全的 第三步&#xff1a;ji活 懂得都懂这是什么 JU090-6039P-08409-8J0QH-2YR7F 4A4RR-813DK-M81A9…

C语言算法--快速排序法

C语言算法–快速排序法 1-什么是快速排序法 快速排序&#xff08;Quicksort&#xff09;是一种常用的排序算法&#xff0c;它基于分治的思想。它的核心思想是选择一个基准元素&#xff0c;将数组划分为两个子数组&#xff0c;使得左边的子数组中的所有元素都小于等于基准元素…

【Flutter开发】Navigator2.0介绍及使用

目录 Navigator1.0Navigator2.0APPRouteInformationParserRouterDelegate 问题The Navigator.pages must not be empty to use the Navigator.pages API浏览器的回退按钮 总结 Navigator1.0 我们学习flutter一开始接触的路由管理就是Navigator1.0&#xff0c;它非常方便&#…

JAVA-Activiti 7与达梦、人大金仓兼容-nacos、服务pom文件配置(2)

目录 第一步,修改nacos服务配置 >需注意< 第二步,pom.xml依赖包配置 Activiti的源码包解决之后,接下来就好做很多了 第一步,修改nacos服务配置 spring:datasource:url: jdbc:kingbase8://127.0.0.1:54321/progress?currentSchemaprogress,productNamePostgreSQL,SYS…

保密+完整+可用+安全,规避代码安全「马奇诺防线」,构建软件供应链整体安全

近日&#xff0c;在「江狐会」广州站上&#xff0c;极狐(GitLab) 高级解决方案架构师武让分享了如何通过三大阶段 四大要点&#xff0c;规避代码安全「马奇诺防线」&#xff0c;真正确保软件供应链安全。以下内容整理自本次演讲。Enjoy&#xff5e; 先跟大家分享一个故事 一战…

计算机体系结构|MIT6.175和MIT6.375学习笔记

在2023年初&#xff0c;达坦科技发起成立硬件设计学习社区&#xff0c;邀请所有有志于从事数字芯片设计的同学加入我们的学习互助自学小组&#xff0c;以理解数字芯片设计的精髓&#xff0c;强化理论知识的同时提升实操技能&#xff0c;继而整体提升设计能力。现在&#xff0c;…

Vmware虚拟机安装MacOS13-Ventura详细教程

小编亲测 前提准备 功能强大的 Windows 电脑&#xff08;不能太差&#xff0c;不然会卡&#xff09;至少8GB内存默认是80GB的存储空间VMWare Workstation&#xff08;版本应该没什么需求&#xff0c;我装的是VMware Workstation 17 Pro&#xff09;Unlocker解锁软件MacOS Ventu…

最快的 Houdini 和 V-Ray 云渲染服务

Houdini是SideFX开发的一款3D动画软件应用。Houdini 最常用于 FX 部门&#xff0c;用于在电影和游戏中创建视觉效果。它被主要的 VFX 公司使用&#xff0c;例如 Walt Disney Animation Studios、Pixar、DreamWorks Animation、Double Negative、ILM、MPC、Framestore 等。Houdi…

推荐几款音频转文字软件给你

不知道小伙伴们有没有遇到过这种情况&#xff0c;在上学时期&#xff0c;我们经常需要记录老师上课的板书内容&#xff0c;但是边听边记可能速度会跟不上&#xff0c;还会遗漏掉一些内容&#xff0c;而且效率也不高。其实这时候&#xff0c;我们可以将老师讲话的内容先录制下来…

鸿蒙Hi3861学习十三-Huawei LiteOS-M(STA模式)

一、简介 AP&#xff08;Access Point&#xff09;无线接入点 AP是无线接入点&#xff0c;是一个无线网络的创建者&#xff0c;是网络的中心节点。一般家庭或办公室使用的无线路由器就是一个AP。 STA&#xff08;Station&#xff09;站点 STA也可以理解为终端的意思&#xff…

高性能零售IT系统的建设10-一个系统日志记录搞崩了整个公司的O2O交易系统

背景 绝大多数业务系统其实都是一座屎山&#xff0c;本人接手的这座屎山目前已经成了一座金山。这其中的幸酸只有那些从0参与过并活到现在的一些“老人”们心中自知其中的滋味。 在3年半前&#xff0c;本以为买来的一套将近600万行代码、达800张表、几乎用到了所有的互联网中间…

分布式系统:高并发

目录 1.什么是高并发 2.术语 3.如何应对处理高并发 3.1.提升系统的并发能力 3.3.1.垂直扩展 3.3.2.水平扩展 3.2.流量控制 4.削峰 4.1.怎样来实现流量削峰方案 4.2.限流 5.总结 1.什么是高并发 高并发是指系统在同一时间内处理大量请求的能力。在软件开发中&a…

CRM管理系统在线用

一、CRM管理系统是什么 CRM是客户关系管理的缩写&#xff0c;是指企业通过建立客户档案、跟进客户需求、提供优质服务来维系客户关系的一种管理模式。是企业以客户关系为重点&#xff0c;通过开展系统化的客户研究&#xff0c;优化企业组织体系和业务流程&#xff0c;提高客户…

Jina AI全新Inference服务,LangChain开发体验从未如此丝滑

由于 Token 的限制&#xff0c;在开发 LangChain 问答机器人应用时&#xff0c;我们经常需要将文档切割&#xff0c;接着使用 Embedding 引擎 分别将分割后的 Document 变成 Embeddings&#xff0c;即向量表示。 同时输入的问题&#xff0c;也需要用到 Embedding 引擎 变成向量…

linux调试知识:手把手教你SSH怎么链接

在机器装机后&#xff0c;如果没有显示&#xff0c;有没有串口&#xff0c;通常很难区操作调试&#xff0c;本文总结一篇通过搭建SSH链接去为调试做服务&#xff1a; 首先第一步&#xff1a;安装必要的软件&#xff0c;CRT或者XSHELL。 下面将举实际案例&#xff0c;手把手搭…

Axure rp9 引入Echarts图表 |手动引入图表 Apache Echarts

Axure rp9 引入Echarts图表 |手动引入图表 Apache Echarts 1.拖入一个矩形lable&#xff0c;调整合适大小,并命名为test 2.给test新建交互载入时&#xff0c;打开链接&#xff0c;并将下方code贴入 如果想在无网的情况下运行&#xff0c;需要在axure软件的安装目录DefaultSet…

深度学习笔记之递归网络(三)递归神经网络

深度学习笔记之递归网络——递归神经网络 引言回顾&#xff1a;潜变量自回归模型递归神经网络思想困惑度 引言 上一节介绍了基于统计算法的语言模型。本节将介绍基于神经网络的序列模型——递归神经网络。 回顾&#xff1a;潜变量自回归模型 关于潜变量自回归模型&#xff0…