java实现图片转pdf,并通过流的方式进行下载(前后端分离)

首先需要导入相关依赖,由于具体依赖本人也不是记得很清楚了,所以简短的说一下。

  1. iText:PDF 操作库,用于创建和操作 PDF 文件。可通过 Maven 或 Gradle 引入 iText 依赖。

  2. MultipartFile:Spring 框架中处理文件上传的类。通常用于接收前端上传的文件数据。

  3. HttpServletRequest:Java Servlet API 中的类,用于获取 HTTP 请求的相关信息,如请求方式、参数等。

  4. BufferedImage:Java 中用于表示图像的类,通常与 ImageIO 结合使用来读取图片文件。

  5. ByteArrayOutputStream:Java 中的字节数组输出流,用于将数据写入到字节数组中。

  6. DocumentPdfWriter:iText 库中的类,分别用于创建 PDF 文档和写入 PDF 文件。

  7. Image:iText 库中的类,用于处理图像,并将图像添加到 PDF 文档中。

  8. Rectangle:iText 库中的类,用于表示 PDF 页面的大小。

 <!--ITextPdf,操作PDF文件的工具类-->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.4.2</version>
        </dependency>
        <dependency>
            <groupId>com.documents4j</groupId>
            <artifactId>documents4j-local</artifactId>
            <version>1.0.3</version>
        </dependency>
        <dependency>
            <groupId>com.documents4j</groupId>
            <artifactId>documents4j-transformer-msoffice-word</artifactId>
            <version>1.0.3</version>
        </dependency>

以上提供一些依赖,是需要用到的,然后在application.yml中添加以下配置:

web:
  upload-path: E:/PictureTool/
  resources:
   static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${web.upload-path}
  • 配置web.upload-path为与项目代码分离的静态资源路径,即:文件上传保存根路径
  • 配置spring.resources.static-locations,除了带上Spring Boot默认的静态资源路径之外,加上file:${web.upload-path}指向外部的文件资源上传路径。该路径下的静态资源可以直接对外提供HTTP访问服务。

然后就需要写具体的实现逻辑了:

 public R imgToPdf(MultipartFile file, HttpServletRequest request) {
        // 获取文件在服务器上的存储路径
        String imagePath = getFilePath(file);
        // 获取文件名,去掉文件扩展名
        String filename = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf("."));
        // 将文件名赋值给成员变量FileName
        FileName = filename;
        try {
            // 使用ImageIO读取文件内容,转换为BufferedImage对象
            BufferedImage img = ImageIO.read(new File(imagePath));
            // 创建一个ByteArrayOutputStream对象,用于存储转换后的PDF文件
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            // 创建一个Document对象,用于存储PDF文档
            Document doc = new Document();
            // 创建一个PdfWriter对象,用于将BufferedImage对象转换为PDF文件
            PdfWriter.getInstance(doc, new FileOutputStream(uploadPath + filename + ".pdf"));
            // 存储PDF文件的路径
            FilePath = uploadPath + filename + ".pdf";
            System.out.println(uploadPath + filename + ".pdf");
            // 打开文档
            doc.open();
            // 将BufferedImage对象添加到PDF文档中
            Image image = Image.getInstance(imagePath);
            // 设置文档的页面大小为BufferedImage的大小
            doc.setPageSize(new Rectangle(img.getWidth(), img.getHeight()));
            // 将BufferedImage对象添加到PDF文档的第一个页面
            doc.add(image);
            // 关闭文档
            doc.close();

            // 调用addUserOperation方法,记录用户操作
            boolean re = addUserOperation(file, "pdf", 1, request);
            System.out.println("转换成功,re为" + re);

            // 获取PDF文件的下载链接
            String downloadLink = request.getScheme() + "://" + request.getServerName() + ":" +
                    request.getServerPort() + request.getContextPath() + "/pictureTool/" + filename + ".pdf";

            // 返回PDF文件的下载链接
            return R.Success("图片转pdf转换成功", downloadLink);
        } catch (Exception e) {
            // 如果转换失败,记录用户操作
            e.printStackTrace();
            boolean re = addUserOperation(file, "pdf", 0, request);
            System.out.println("转换失败,re为" + re);
            // 返回错误信息
            return R.Failed(500, "图片转换失败");
        }
    }

以上代码接受一个文件,然后进行转换为pdf并保存在本地指定的文件夹中,接下来使用输出流的方式进行文件下载。

 public R downloadFile(HttpServletRequest request, HttpServletResponse response)
            throws IOException {

        // 获取文件路径和文件名
        String filePath = FilePath;
        String fileName = FileName;

        // 设置响应头,指定下载文件的名称
        response.setHeader("Content-Disposition",
                "attachment; filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));

        try {
            // 打开文件
            File file = new File(filePath);
            FileInputStream fileInputStream = new FileInputStream(file);

            // 读取文件内容到字节数组
            byte[] fileByte = new byte[(int) file.length()];
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] bytes = new byte[1024];
            int len;
            while ((len = fileInputStream.read(bytes, 0, bytes.length)) != -1) {
                byteArrayOutputStream.write(bytes, 0, len);
            }
            byteArrayOutputStream.close();
            fileByte = byteArrayOutputStream.toByteArray();

            // 将文件内容写入响应对象
            OutputStream outputStream = response.getOutputStream();
            outputStream.write(fileByte);
            outputStream.flush();
            outputStream.close();

            // 返回成功信息
            return R.Success("文件下载成功");
        } catch (Exception e) {
            // 如果下载失败,返回失败信息
            e.printStackTrace();
            return R.Failed("文件下载失败");
        }
    }

其中R是我自定义的一个响应类,改成你自己的就可以了~

最后,记得放行你存放文件的盘符:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis 学习(四)之 SQL 映射文件

目录 1 SQL 映射文件介绍 2 select 元素 3 insert 元素 4 update 和 delete 元素 5 sql 元素 6 parameterType 元素 7 resultType 元素 8 resultMap 元素&#xff08;重要&#xff09; 9 参考文档 1 SQL 映射文件介绍 映射器是 MyBatis 中最复杂并且是最重要的…

机器学习 -- 梯度下降算法加深

梯度下降算法 在机器学习中&#xff0c;梯度下降算法常用于最小化代价函数&#xff08;或损失函数&#xff09;&#xff0c;以此来优化模型的参数。代价函数衡量的是模型预测值与实际值之间的差异。通过最小化这个函数&#xff0c;我们可以找到模型预测最准确的参数。 代价函…

蓝桥杯-单片机组基础6——定时计数器与外部中断混合使用(附小蜜蜂课程代码)

蓝桥杯单片机组备赛指南请查看这篇文章&#xff1a;戳此跳转蓝桥杯备赛指南文章 本文章针对蓝桥杯-单片机组比赛开发板所写&#xff0c;代码可直接在比赛开发板上使用。 型号&#xff1a;国信天长4T开发板&#xff08;绿板&#xff09;&#xff0c;芯片&#xff1a;IAP15F2K6…

Android 混淆是啥玩意儿?

什么是混淆 Android混淆&#xff0c;是伴随着Android系统的流行而产生的一种Android APP保护技术&#xff0c;用于保护APP不被破解和逆向分析。简单的说&#xff0c;就是将原本正常的项目文件&#xff0c;对其类、方法、字段&#xff0c;重新命名a,b,c…之类的字母&#xff0c…

[AutoSar]BSW_Com07 CAN报文接收流程的函数调用

目录 关键词平台说明一、背景二、顺序总览三、函数说明3.1 Com_RxIndication&#xff08;&#xff09; 关键词 嵌入式、C语言、autosar、OS、BSW 平台说明 项目ValueOSautosar OSautosar厂商vector &#xff0c;芯片厂商TI 英飞凌编程语言C&#xff0c;C编译器HighTec (GCC)…

win11安装nodejs

一、下载安装包 链接: https://pan.baidu.com/s/1_df8s1UlgNNaewWrWgI59A?pwdpsjm 提取码: psjm 二、安装步骤 1.双击安装包 2.Next> 3.勾选之后&#xff0c;Next> 4.点击Change&#xff0c;选择你要安装的路径&#xff0c;然后Next> 5.点击Install安装 二、…

MySQL 存储过程批量插入总结

功能需求背景&#xff1a;今天接到产品经理核心业务表的数据压测功能&#xff0c;让我向核心业务表插入百万级的业务量数据&#xff0c;我首先想到的办法就是存储过程实现数据的批量 。 由于无法提供核心业务表&#xff0c;本文仅仅提供我刚刚自己创建的表bds_base_user 表做相…

【Vue3】深入理解Vue中的ref属性

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

VSCode通过SSH连接Docker环境进行开发

文章目录 VSCode 插件Docker 镜像构建镜像部署环境 VSCode 连接本地Docker容器VSCode SSH连接Docker容器VSCode 打开容器内目录文件 VSCode 插件 Remote - SSH Docker 镜像 https://hub.docker.com/_/golang # Golang 镜像 docker pull golang:1.22构建镜像 Dockerfile F…

Shell条件判断

一、文件类型判断 示例&#xff1a; # 判断文件是否存在&#xff0c;存在为0&#xff0c; 不存在为1 [rootlocalhost ~]# test -e person.txt [rootlocalhost ~]# echo $? 0 [rootlocalhost ~]# [rootlocalhost ~]# test -e aba [rootlocalhost ~]# echo $? 1 # 出test外&am…

SaaS 电商设计 (九) 动态化且易扩展的实现购物车底部弹层(附:一套普适的线上功能切量的发布方案)

目录 一.背景1.1 业务背景1.2 技术负债 二.技术目标三.方案设计3.1 解决移动端频繁发版3.1.1 场景分析3.1.2 技术方案 3.2 减少后端坏味道代码&无法灵活扩展问题3.2.1 通过抽象接口完成各自单独楼层渲染逻辑3.2.2 通过配置能力做到部分字段可配 四.升级上线(普适于高并发大…

小程序实现定位城市切换且城市根据首字母A-Z排序后端数据实现逻辑

场景&#xff1a; 话不多说后端提供数据实现步骤&#xff1a; 1.controller层 Api(tags {"[地区]-城市相关接口"}) RestController RequestMapping("region") Slf4j public class RegionController extends BaseController {Resourceprivate RegionServ…

盲人出行:科技创造美好的未来

在繁忙的都市中&#xff0c;我每天都要面对许多挑战&#xff0c;盲人出行安全保障一直难以得到落实。我看不见这个世界&#xff0c;只能依靠触觉和听觉来感知周围的一切。然而&#xff0c;我从未放弃过对生活的热爱和对未来的憧憬。在一次机缘巧合下&#xff0c;我认识了一款名…

信息系统项目管理师--项目管理概述

开展项⽬是为了通过可交付成果达成⽬标。⽬标是所指向的结果、要取得的战略地位、要达到的⽬的、要获得的成果、要⽣产的产品或者要提供的服务。 可交付成果形成的独特并可验证的产品、成果或服务。可交付成果可能是有形的&#xff0c;也可能是⽆形的。产⽣⼀个或多个可交付成…

【ArcGIS】渔网分割提取栅格图+网格化分析图绘制

ArcGIS按渔网分割提取栅格图并绘制网格化分析图 准备数据操作步骤步骤1&#xff1a;创建渔网&#xff08;Create Fishnet&#xff09;步骤2&#xff1a;栅格数据处理步骤3&#xff1a;栅格插值步骤4&#xff1a;数据关联 参考 网格化的目的是让各个数据更加标准化的进行统计。因…

C语言-指针(上)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 本篇文章将为大家介绍C语言中的核心内容-指针&#xff0c;指针在C语言的中知识内容比…

全新挑战:微软 AI 奥德赛邀您全方位 Get AI 应用技能!

点击蓝字 关注我们 AI 风暴的火速席卷&#xff0c;大语言模型的不断迭代&#xff0c;在企业面临着机遇与挑战并存的新形势下&#xff0c;许许多多的个人也在经历着职业生涯的巨大压力与变革。在这场人工智能的浪潮之中&#xff0c;AI 技能无疑是我们破局焕新的关键利器。 为助力…

Dell R730 2U服务器实践3:安装英伟达上代专业AI训练Nvidia P4计算卡

Dell R730是一款非常流行的服务器&#xff0c;2U的机箱可以放入两张显卡&#xff0c;这次先用一张英伟达上代专业级AI训练卡&#xff1a;P4卡做实验&#xff0c;本文记录安装过程。 简洁步骤&#xff1a; 打开机箱将P4显卡插在4号槽位关闭机箱安装驱动 详细步骤&#xff1a; 对…

k8s单机部署zookeeper

&#xff08;作者&#xff1a;陈玓玏&#xff09; 拉取镜像&#xff1a;docker pull zookeeper&#xff1b;编辑yaml&#xff1a; apiVersion: v1 kind: Service metadata:name: zookeeperlabels:app: zookeeper spec:ports:- name: clientport: 2181protocol: TCPtargetP…

图片说话软件一览

目录 ~~tokkingheads~~~~myvoiceyourface~~~~avatarify~~wav2lip(值得研究) 最近刷到很多古画唱歌视频&#xff0c;搜了一下&#xff0c;好多教你怎么做的&#xff0c;今天来尝试了一下&#xff0c;感觉不咋地&#xff0c;就没有成功的 tokkingheads 网页一直转圈&#xff0c;…