在springboot项目中实现将上传的jpg图片类型转为pdf并保存到本地

前言:前端使用uniapp中的uni.canvasToTempFilePath方法将画板中的内容保存为jpg上传至后端处理

uni.canvasToTempFilePath({
                canvasId: 'firstCanvas',
				sourceType: ['album'],
				fileType: "jpg",
                success: function (res1) {
					let signature_base64 = res1.tempFilePath;
					
					let signature_file = that.base64toFile(signature_base64);
					// 将签名存储到服务器
					uni.uploadFile({
						url: "convertJpgToPdf",
						name: "file",
						file: signature_file,
						formData: {
							busiId: 'ceshi12',
							token: token
						},
						success: function (res1) {
							console.log(res1);
						}
					})
                }
            });

// 将base64转为file
		base64toFile: function(base64String) {
		    // 从base64字符串中解析文件类型
			var mimeType = base64String.match(/^data:(.*);base64,/)[1];
			// 生成随机文件名
			var randomName = Math.random().toString(36).substring(7);
			var filename = randomName + '.' + mimeType.split('/')[1];
			
			let arr = base64String.split(",");
			let bstr = atob(arr[1]);
			let n = bstr.length;
			let u8arr = new Uint8Array(n);
			while (n--) {
				u8arr[n] = bstr.charCodeAt(n);
			}
			return new File([u8arr], filename, { type: mimeType });
		},

java代码:
首先在pom.xml中安装依赖

<dependency>
	<groupId>org.apache.pdfbox</groupId>
	<artifactId>pdfbox</artifactId>
	<version>2.0.8</version>
</dependency>

使用方法:

/**
     * 将jpg转为pdf文件
     * @param jpgFile
     * @return
     * @throws IOException
     */
    public MultipartFile convertJpgToPdf(MultipartFile jpgFile) throws IOException {
        // 保存MultipartFile到临时文件
        File tempFile = new File(System.getProperty("java.io.tmpdir"), "temp.jpg");
        jpgFile.transferTo(tempFile);
        // 创建PDF文档
        PDDocument pdfDoc = new PDDocument();
        PDPage pdfPage = new PDPage();
        pdfDoc.addPage(pdfPage);

        // 从临时文件创建PDImageXObject
        PDImageXObject pdImage = PDImageXObject.createFromFile(tempFile.getAbsolutePath(), pdfDoc);

        // 获取PDF页面的内容流以添加图像
        PDPageContentStream contentStream = new PDPageContentStream(pdfDoc, pdfPage);

        // 获取PDF页面的大小
        PDRectangle pageSize = pdfPage.getMediaBox();
        float pageWidth = pageSize.getWidth();
        float pageHeight = pageSize.getHeight();

        // 在PDF页面上绘制图像
        float originalImageWidth = pdImage.getWidth();
        float originalImageHeight = pdImage.getHeight();

        // 初始化缩放比例
        float scale = 1.0f;

        // 判断是否需要缩放图片
        if (originalImageWidth > pageWidth || originalImageHeight > pageHeight) {
            // 计算宽度和高度的缩放比例,取较小值
            float widthScale = pageWidth / originalImageWidth;
            float heightScale = pageHeight / originalImageHeight;
            scale = Math.min(widthScale, heightScale);
        }
        // 计算缩放后的图片宽度和高度
        float scaledImageWidth = originalImageWidth * scale;
        float scaledImageHeight = originalImageHeight * scale;

        // 计算图片在页面中居中绘制的位置
        float x = (pageWidth - scaledImageWidth) / 2;
        float y = (pageHeight - scaledImageHeight) / 2;

        // 绘制缩放后的图片到PDF页面
        contentStream.drawImage(pdImage, x, y, scaledImageWidth, scaledImageHeight);
        // 关闭内容流
        contentStream.close();

        // 将PDF文档写入到字节数组中
        ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();
        pdfDoc.save(pdfOutputStream);

        // 关闭PDF文档
        pdfDoc.close();

        // 删除临时文件
        tempFile.delete();

        // 创建代表PDF的MultipartFile
        MultipartFile pdfFile = new MockMultipartFile("converted12.pdf", "converted12.pdf", "application/pdf", pdfOutputStream.toByteArray());
        saveFileToLocalDisk(pdfFile, "D:/");
        return pdfFile;
    }

/**
     * 将MultipartFile file文件保存到本地磁盘
     * @param file
     * @param directoryPath
     * @throws IOException
     */
    public void saveFileToLocalDisk(MultipartFile file, String directoryPath) throws IOException {
        // 获取文件名
        String fileName = file.getOriginalFilename();

        // 创建目标文件
        File targetFile = new File(directoryPath + File.separator + fileName);

        // 将文件内容写入目标文件
        try (FileOutputStream outputStream = new FileOutputStream(targetFile)) {
            outputStream.write(file.getBytes());
        } catch (IOException e) {
            // 处理异常
            e.printStackTrace();
            throw e;
        }
    }

MockMultipartFile类

package com.jiuzhu.server.common;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

public class MockMultipartFile implements MultipartFile {
    private final String name;

    private String originalFilename;

    private String contentType;

    private final byte[] content;

    /**
     * Create a new MultipartFileDto with the given content.
     *
     * @param name    the name of the file
     * @param content the content of the file
     */
    public MockMultipartFile(String name, byte[] content) {
        this(name, "", null, content);
    }

    /**
     * Create a new MultipartFileDto with the given content.
     *
     * @param name          the name of the file
     * @param contentStream the content of the file as stream
     * @throws IOException if reading from the stream failed
     */
    public MockMultipartFile(String name, InputStream contentStream) throws IOException {
        this(name, "", null, FileCopyUtils.copyToByteArray(contentStream));
    }

    /**
     * Create a new MultipartFileDto with the given content.
     *
     * @param name             the name of the file
     * @param originalFilename the original filename (as on the client's machine)
     * @param contentType      the content type (if known)
     * @param content          the content of the file
     */
    public MockMultipartFile(String name, String originalFilename, String contentType, byte[] content) {
        this.name = name;
        this.originalFilename = (originalFilename != null ? originalFilename : "");
        this.contentType = contentType;
        this.content = (content != null ? content : new byte[0]);
    }

    /**
     * Create a new MultipartFileDto with the given content.
     *
     * @param name             the name of the file
     * @param originalFilename the original filename (as on the client's machine)
     * @param contentType      the content type (if known)
     * @param contentStream    the content of the file as stream
     * @throws IOException if reading from the stream failed
     */
    public MockMultipartFile(String name, String originalFilename, String contentType, InputStream contentStream)
            throws IOException {

        this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream));
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public String getOriginalFilename() {
        return this.originalFilename;
    }

    @Override
    public String getContentType() {
        return this.contentType;
    }

    @Override
    public boolean isEmpty() {
        return (this.content.length == 0);
    }

    @Override
    public long getSize() {
        return this.content.length;
    }

    @Override
    public byte[] getBytes() throws IOException {
        return this.content;
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return new ByteArrayInputStream(this.content);
    }

    @Override
    public void transferTo(File dest) throws IOException, IllegalStateException {
        FileCopyUtils.copy(this.content, dest);
    }
}

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

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

相关文章

MATLAB 数据输出

MATLAB 数据输出 数据导出(或输出)在 MATLAB 的意思是写入文件。MATLAB 允许您在另一个读取 ASCII 文件的应用程序中使用您的数据。为此&#xff0c;MATLAB 提供了几个数据导出选项。 您可以创建以下类型的文件- 数组中的矩形、分隔的ASCII数据文件。 击键的日记&#xff08…

Linux系统安装Redis7(详细版)

Linux系统安装Redis7 一、windows安装redis二、Linux安装Redis下载redis编辑redis7.conf文件启动redis-server服务如何关闭redis服务设置Redis开机自启动 一、windows安装redis Window 下安装 下载地址&#xff1a;https://github.com/dmajkic/redis/downloads 下载到的Redi…

6.k8s中的secrets资源

一、Secret secrets资源&#xff0c;类似于configmap资源&#xff0c;只是secrets资源是用来传递重要的信息的&#xff1b; secret资源就是将value的值使用base64编译后传输&#xff0c;当pod引用secret后&#xff0c;k8s会自动将其base64的编码&#xff0c;反编译回正常的字符…

OpenCV(一) —— OpenCV 基础

1、OpenCV 简介 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个基于 BSD 许可开源发行的跨平台的计算机视觉库。可用于开发实时的图像处理、计算机视觉以及模式识别程序。由英特尔公司发起并参与开发&#xff0c;以 BSD 许可证授权发行&#xff0c…

【QT学习】14.线程学习

一。线程了解 线程是计算机科学中的一个重要概念&#xff0c;它是操作系统能够进行运算调度的最小单位。线程是进程中的一个执行流&#xff0c;一个进程可以包含多个线程。与进程相比&#xff0c;线程更轻量级&#xff0c;可以更高效地利用计算机资源。 线程有以下几个特点&…

vue3+ts 原生 js drag drop 实现

vue3ts 原生 js drag drop 实现 一直以来没有涉及的一个领域就是 drag drop 拖动操作&#xff0c;研究了下&#xff0c;实现了&#xff0c;所以写个教程。 官方说明页面及实例&#xff1a;https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API 最终效果&…

企业计算机服务器中了lockbit勒索病毒如何处理,lockbit勒索病毒解密流程建议

在虚拟的网络世界里&#xff0c;人们利用网络获取信息的方式有很多&#xff0c;网络为众多企业提供了极大便利性&#xff0c;也大大提高了企业生产运营效率&#xff0c;方便企业开展各项工作业务。但随着网络技术的不断发展与应用&#xff0c;越来越多的企业开始关注企业网络数…

Flutter笔记:Widgets Easier组件库(8)使用图片

Flutter笔记 Widgets Easier组件库&#xff08;8&#xff09;&#xff1a;使用图片 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress o…

使用递归函数,将一串数字每位数相加求和

代码结果&#xff1a; #include<stdio.h> int DigitSum(unsigned int n) {if (n > 9)return DigitSum(n / 10) (n % 10);elsereturn n; } int main() {unsigned int n;scanf("%u", &n);int sum DigitSum(n);printf("%d\n", sum);return 0; …

C语言/数据结构——每日一题(合并两个有序链表)

一.前言 嗨嗨嗨&#xff0c;大家好久不见&#xff01;今天我在LeetCode看到了一道单链表题&#xff1a;https://leetcode.cn/problems/merge-two-sorted-lists想着和大家分享一下&#xff0c;废话不多说&#xff0c;让我们开始今天的题目分享吧。 二.正文 1.1题目描述 1.2题…

Javascript:Web APIs(二)

JavaScript&#xff1a;Web APIs&#xff08;一&#xff09; 在上篇文章&#xff0c;我们学习了对BOM对象的一些基本操作&#xff0c;但即使这样&#xff0c;我们也只是能通过js改变元素属性&#xff0c;而不能进行网页的交互效果和动态效果&#xff0c;这时我们就不得不提到事…

Spring Cloud——LoadBalancer

Spring Cloud——LoadBalancer 一、负载均衡&#xff08;LoadBalance&#xff09;1.LoadBalancer本地负载均衡客户端 VS Nginx服务端负载均衡区别 二、LoadBalancer1.Spring RestTemplate as a LoadBalancer Client2.编码使用DiscoveryClient动态获取所有上线的服务列表3.从默认…

QT5之lambda+内存回收机制

使用lambda需要 配置c11 所以在点.pro文件里面配置添加如下 CONFIG c11 使用到qDebug 打印包含头文件 #include<QDebug> lambda 表达式使用 代替槽如下 #include "mainwidget.h" #include<QPushButton> #include<QDebug> mainWidget::mainWid…

探索AI工具的巅峰:个人体验与深度剖析

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-6.4--汇编LED驱动程序

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

省级财政收入、支出、第一、二、三产业增加值、工业增加值、金融业增加值占GDP比重数据(1978-2022年)

01、数据介绍 财政收支作为国家治理的基础&#xff0c;越来越受到社会各界的关注。同时&#xff0c;产业结构的优化与升级也是中国经济持续增长的关键因素。本数据对中国省级财政收入、支出占GDP的比重以及第一、二、三产业的增加值占GDP的比重和工业增加值占GDP的比重、金融业…

Python量化炒股的财务因子选股—质量因子选股

Python量化炒股的财务因子选股—质量因子选股 在Python财务因子量化选股中&#xff0c;质量类因子有2个&#xff0c;分别是净资产收益率和总资产净利率。需要注意的是&#xff0c;质量类因子在财务指标数据表indicator中。 净资产收益率&#xff08;roe&#xff09;选股 净资…

创建codereview

创建codereview流程 一、开始创建二、选择分支三、添加细节 一、开始创建 点击codereivew按钮 为新的codereview选择一个工程后点击create review 二、选择分支 选择目标分支和要比对的分支&#xff0c;比如develop 三、添加细节 Add branch后&#xff0c;可以继续Edit …

如何反向查看某个命令所属的rpm包的2个方法?(rpm -qf `which xxx`和yum provides和 rpm -ql xxx.rpm)

文章目录 快速回忆方法1&#xff1a; rpm -qf方法2&#xff1a;yum provides 其他rpm如何查看某个rpm包里面包含哪些命令: rpm -ql主推方法1&#xff1a; rpm -ql方法2&#xff1a;yum info 其他查看rdma-core中包含哪些cmd&#xff1a;一些其他命令所在包探索 快速回忆 rpm -…

C++_set和map的学习

1. 关联式容器 STL中的容器有序列式容器和关联式容器。 其中 vector 、 list 、 deque 、 forward_list(C11)就是序列式容器&#xff0c; 因为其底层为线性序列的数据结构&#xff0c;里面 存储的是元素本身 关联式容器 也是用来存储数据的&#xff0c;与序列式容器不同的是&am…
最新文章