VUE:SpringBoot + Vue 尝鲜,PDF转换例子

博主分享了如何在众多收费的PDF转换软件中,通过开源代码自建一个免费的PDF转图片工具。文章详细展示了前端使用Vue.js实现文件上传和转换触发,后端利用IcePDF库进行转换,并提供了压缩下载的功能。此外,还讨论了市场上诱导付费的现象。
摘要由CSDN通过智能技术生成

最近收到很多文件,为了保持格式统一,需要统一保存为PDF,但是现在在网上搜索下PDF相关的转换软件,号称免费的给你转前几页(日常简单任务已经可以胜任了,可以先pdf拆分后在转换),要不就是收费的,要不号称免费但进去后还是收费的,还有转换是免费的,下载是收费的。

请添加图片描述
上图说什么我也不知道的,动图没有文字。

不过大多数提供的功能还是比较完善的,知识付费时代提供服务收取一定费用无可厚非,但是诱导付费行为不值得提倡,前段时间听说有个公司提供VS Code下载还要收费的,这是真的么。

说这么多呢,其实就是一个原因 我想(bai) (piao),怎么实现这个愿望呢,那么自己尝试实现一个吧。下面以PDF转图片举例看下实现过程,PDF转换在网上有很多开源代码,大家可以尝试下

本人CSS小白,不会修改样式,大家将就看看就可以哈

PDF转图片页面
在这里插入图片描述
转换后直接生成target压缩包下载

在这里插入图片描述

前端实现
<template>
	<el-card>
		<el-row :gutter="10">
			<el-col :span="12">
				<h4 class="mgb20">PDF转图片</h4>
			</el-col>
			<el-col :span="12" align="right">
				<el-button @click=""><i class="icon-heart" style="margin-right: 5px;"></i> <span>点赞</span>
					(<span>12345</span>)</el-button>
			</el-col>
		</el-row>
		<el-row :gutter="10">
			<el-col :span="24">
				<el-card class="mgb20">
					<el-upload ref="upload" class="upload-demo" drag action="#" :auto-upload="false" :limit="1" :before-upload="beforeUpload"
						:http-request="uploadFile">
						<i class="el-icon-upload"></i>
						<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
						<div class="el-upload__tip" slot="tip">只能上传PDF文件,且不超过500kb</div>
					</el-upload>
				</el-card>
			</el-col>
		</el-row>
		<el-row>
			<el-col>
				<el-button type="success" @click="submitUpload">转换</el-button>
			</el-col>
		</el-row>
	</el-card>
</template>

<script>
	import axios from 'axios';
	let server = axios.create({
		transformRequest: [
			function(data) {
				let ret = ''
				for (let it in data) {
					ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
				}
				ret = ret.substring(0, ret.lastIndexOf('&'));
				return ret
			}
		],
		headers: {
			'Content-Type': 'application/x-www-form-urlencoded'
		}
	});
	export default {
		data() {
			return {
				user: JSON.parse(localStorage.getItem('wr_user')),
				fileList: [],
				thumbs: ''
			}
		},
		created() {
	
		},
		methods: {	
			//校验格式
			beforeUpload(file) {
				const isPDF = file.type === 'application/pdf';
				if(!isPDF) {
					this.$message.warning('只支持PDF格式文件');
					return false;
				}
			},

			uploadFile(file) {
				const loading = this.$loading({
				    lock: true,
				    text: '转换中,请等待',
				    spinner: 'el-icon-loading',
				    background: 'rgba(0, 0, 0, 0.7)'
				});
				// 把文件放入 FormData 进行提交
				const param = new FormData()
				if (undefined !== file) {
					param.append('files', file.file)
				}
				param.append("username", this.user.username)

				axios({
					url: "/pdf/tools/pdf2img",
					method: "post",
					responseType: 'blob', //不可省,非常重要
					data: param
				}).then((res) => {
					if(res.data.type === 'text/xml') {
						let fileName = window.decodeURI(res.headers['content-disposition'].split('=')[1]);
						let contentType = res.headers['content-type'];
						let blob = new Blob([res.data], {
							type: contentType + ';charset=utf-8'
						});
						let downloadElement = document.createElement('a');
						let href = window.URL.createObjectURL(blob); //创建下载的链接
						downloadElement.href = href;
						downloadElement.download = fileName; //下载后文件名
						document.body.appendChild(downloadElement);
						downloadElement.click(); //点击下载
						document.body.removeChild(downloadElement); //下载完成移除元素
						window.URL.revokeObjectURL(href); //释放掉blob对象
						
						this.$refs.upload.clearFiles();
						if (res.status == 200) {
							this.$message.warning("执行成功");
						} else {
							this.$message.warning("执行失败");
						}
					} else {
						this.$message.warning("请求过于频繁,请稍后再试");
					}
					
					loading.close();
				})
			},

			submitUpload() {
				this.$refs.upload.submit();
			},
		}

	}
</script>

<style>
</style>

后端实现

1、添加maven依赖

<dependency>
    <groupId>org.icepdf.os</groupId>
    <artifactId>icepdf-core</artifactId>
    <version>6.1.2</version>
    <exclusions>
        <exclusion>
            <groupId>javax.media</groupId>
            <artifactId>jai-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>

2、java pdf转img实现

/**
 * 将pdf文件转换为图片
 *
 * @param pdfPath           pdf文件路径
 * @param imagePath         文件存储路径
 * @param imageNamePrefix   保存图片名称前缀
 * @param imageType         保存图片类型
 * @param scale             图片缩放
 * @param rotation          图片旋转
 * @throws IOException
 * @throws PDFException
 * @throws PDFSecurityException
 */

public static List<String> pdf2img(String pdfPath, String imagePath, String imageNamePrefix, String imageType, float scale, float rotation) throws IOException, PDFException, PDFSecurityException {
    List<String> imageList = new ArrayList<>();
    Document document = new Document();
    document.setFile(pdfPath);

    for (int i = 0; i < document.getNumberOfPages(); i++) {
        BufferedImage image = (BufferedImage)document.getPageImage(i, GraphicsRenderingHints.SCREEN, Page.BOUNDARY_CROPBOX, rotation, scale);
        RenderedImage rendImage = image;
        try {
            if("".equals(imageNamePrefix) || null == imageNamePrefix) {
                imageNamePrefix = new File(pdfPath).getName();
            }
            String imgName = imageNamePrefix + "_" + new DecimalFormat("000").format(i) + "." + imageType;
            String savePath = "";
            if("/".equals(imagePath.substring(imagePath.length()-1))) {
                savePath = imagePath + imgName;
            } else {
                savePath = imagePath + "/" + imgName;
            }
            File file = new File(savePath);
            File fileParent = file.getParentFile();
            if (!fileParent.exists()) {
                fileParent.mkdirs();
            }
            if (!file.exists()) {
                file.createNewFile();
            }
            ImageIO.write(rendImage, imageType, file);
            // 保存文件路径
            imageList.add(savePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
        image.flush();
    }
    document.dispose();
    System.out.println("转换完成");
    return imageList;
}

3、controller层

@RequestMapping("/pdf2img")
@ResponseBody
public void pdf2img(@RequestParam("files") MultipartFile[] files,
                       @RequestParam("username") String username,
                       HttpServletResponse response) throws IOException, PDFException, PDFSecurityException {
    List<String> result = new ArrayList<>();
    // 注意:rootPath, pdfPath, imagePath 文件路径修改为自己需要的文件路径
    String rootPath = getPath(FileType.TYPE.ROOT.getCode(), username);
    String pdfPath = getPath(FileType.TYPE.PDF.getCode(), username);
    String imagePath = getPath(FileType.TYPE.IMG.getCode(), username);
    for (MultipartFile file : files) {
        String filename = file.getOriginalFilename();
        FileUtils.createFile(file, pdfPath, filename);
        result = PDFUtils.pdf2img(pdfPath + filename, imagePath, "target", "jpg", 2.5f, 0f);
    }

    // 打包文件
    String zipPath = imagePath + "target.zip";
    FileOutputStream fos = new FileOutputStream(zipPath);
    List<File> fileList = new ArrayList<>();
    for (String path : result) {
        fileList.add(new File(path));
    }
    ZipUtils.toZip(fileList, fos);

    String fileName = zipPath.substring(zipPath.lastIndexOf("/") + 1);
    response.reset();
    response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));

    //读取指定路径下面的文件
    InputStream in = new FileInputStream(zipPath);

    OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
    response(in, outputStream);
}

4、压缩工具

 /**
 * 文件列表压缩成ZIP
 *
 * @param srcFiles 需要压缩的文件列表
 * @param out      压缩文件输出流
 * @throws RuntimeException 压缩失败会抛出运行时异常
 */
public static void toZip(List<File> srcFiles, OutputStream out) throws RuntimeException {
    long start = System.currentTimeMillis();
    ZipOutputStream zos = null;
    try {
        zos = new ZipOutputStream(out);
        for (File srcFile : srcFiles) {
            byte[] buf = new byte[1024];
            zos.putNextEntry(new ZipEntry(srcFile.getName()));
            int len;
            FileInputStream in = new FileInputStream(srcFile);
            while ((len = in.read(buf)) != -1) {
                zos.write(buf, 0, len);
            }
            zos.closeEntry();
            in.close();
        }
        long end = System.currentTimeMillis();
        System.out.println("压缩完成,耗时:" + (end - start) + " ms");
    } catch (Exception e) {
        throw new RuntimeException("zip error from ZipUtils", e);
    } finally {
        if (zos != null) {
            try {
                zos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值