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

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

javascript 复制代码
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中安装依赖

java 复制代码
<dependency>
	<groupId>org.apache.pdfbox</groupId>
	<artifactId>pdfbox</artifactId>
	<version>2.0.8</version>
</dependency>

使用方法:

java 复制代码
/**
     * 将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类

java 复制代码
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);
    }
}
相关推荐
wellc33 分钟前
SpringBoot集成Flowable
java·spring boot·后端
Hui Baby1 小时前
springAi+MCP三种
java
hsjcjh1 小时前
【MySQL】C# 连接MySQL
java
敖正炀1 小时前
LinkedBlockingDeque详解
java
wangyadong3171 小时前
datagrip 链接mysql 报错
java
untE EADO1 小时前
Tomcat的server.xml配置详解
xml·java·tomcat
ictI CABL2 小时前
Tomcat 乱码问题彻底解决
java·tomcat
敖正炀2 小时前
DelayQueue 详解
java
敖正炀2 小时前
PriorityBlockingQueue 详解
java
shark22222222 小时前
Spring 的三种注入方式?
java·数据库·spring