目录
一、开发思绪
1.1 申请微信小步伐
1.2 编写后端接口
1.3 后端接口摆设
1.4 微信小步伐前端页面开发
1.5 运行效果
1.6 小步伐摆设上线
本日给大家分享小步伐开发系列,PDF转换为图片工具的开发实战,感爱好的朋友可以一起来学习一下!
一、开发思绪
- 申请微信小步伐
- 编写后端接口
- 后端接口摆设
- 微信小步伐前端页面开发
- 微信小步伐摆设上线
1.1 申请微信小步伐
关于怎样申请微信小步伐这里就不外多先容了,大家可以参考腾讯官方的文档,内里先容的非常详细。
1.2 编写后端接口
这里使用Java编程语言的SpringBoot框架来快速搭建WebAPI服务。由于涉及到PDF转换为图片,这里使用spire.pdf来实现。首先引入依靠项
- <dependency>
- <groupId>e-iceblue</groupId>
- <artifactId>spire.pdf.free</artifactId>
- <version>2.6.3</version>
- <scope>provided</scope>
- </dependency>
复制代码
新建PdfUtils.java工具类库用来实现PDF转换为图片的功能
思绪:通过微信小步伐传递过来的文件转换为InputStream输出流,然后保存到服务器端,由于PDF可能涉及有多页,每一页单独为一个图片文件,然后调用图片拼接的方法实现全部页面图片归并为一张长图。注意:免费的spire.pdf支持10页之内的pdf转换,大家如果更高需求,可以考虑购买收费版。
主要代码如下:转换方法主函数
- [/code] [code] /**
- * 根据文件流转换为图片
- *
- * @param stream
- * @return
- */
- public String pdftoimage(InputStream stream, String fileNameOld) {
- Date currentDate = new Date();
- SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss_SSS"); // 指定日期格式,包含毫秒
- String formattedDate = sdf.format(currentDate);
- String pathPath = "/mnt/files/" + formattedDate + "_" + fileNameOld;
- // 4、最终生成的doc所在的目录,默认是和引入的一个地方,开源时对外提供下载的接口。
- saveInputStreamToFile(stream, pathPath);
- String fileName = "result" + formattedDate + ".png";
- String desPath = "/mnt/files/" + fileName; // 构造文件名
- String sux = fileNameOld + "_" + formattedDate;// 临时文件前缀
- boolean result = false;
- try {
- // 0、判断输入的是否是pdf文件
- //第一步:判断输入的是否合法
- //boolean flag = isPDFFile(srcPath);
- //第二步:在输入的路径下新建文件夹
- boolean flag1 = create();
- if (flag1) {
- // 1、加载pdf
- PdfDocument pdf = new PdfDocument();
- //pdf.loadFromStream(stream);
- pdf.loadFromFile(pathPath);
- PdfPageCollection num = pdf.getPages();
- // 2、如果pdf的页数小于11,那么直接进行转化
- if (num.getCount() <= 10) {
- try {
- for (int i = 0; i < pdf.getPages().getCount(); i++) {
- BufferedImage image = pdf.saveAsImage(i, PdfImageType.Bitmap, 300, 300);
- String imgTemp = imgPath + sux + (i + 1) + ".png"; // 构造输出文件路径
- ImageIO.write(image, "PNG", new File(imgTemp));
- }
- pdf.close();
- System.out.println("PDF转图片完成!");
- MergeWordDocument.mergeImage(imgPath, desPath, sux);
- clearFiles(imgPath, formattedDate);
- clearFiles(pathPath, formattedDate);
- } catch (IOException e) {
- e.printStackTrace();
- System.out.println("PDF转图片失败: " + e.getMessage());
- }
- }
- // 3、否则输入的页数比较多,就开始进行切分再转化
- else {
- try {
- for (int i = 0; i < 10; i++) {
- BufferedImage image = pdf.saveAsImage(i, PdfImageType.Bitmap, 300, 300);
- String imgTemp = imgPath + sux + (i + 1) + ".png"; // 构造输出文件路径
- ImageIO.write(image, "PNG", new File(imgTemp));
- }
- pdf.close();
- System.out.println("PDF转图片完成!");
- MergeWordDocument.mergeImage(imgPath, desPath, sux);
- } catch (IOException e) {
- e.printStackTrace();
- System.out.println("PDF转图片失败: " + e.getMessage());
- } finally {
- //clearFiles(imgPath);
- clearFiles(pathPath, formattedDate);
- }
- }
- } else {
- System.out.println("输入的不是pdf文件");
- fileName = "";
- return fileName;
- }
- } catch (Exception e) {
- fileName = "";
- e.printStackTrace();
- } finally {
- //4、把刚刚缓存的split和doc删除
- if (result == true) {
- clearFiles(pathPath, formattedDate);
- clearFiles(splitPath, formattedDate);
- clearFiles(docPath, formattedDate);
- }
- }
- return fileName;
- }
复制代码 保存PDF文件到当地,然后使用后删除
- /**
- * 保存原始的pdf文件为了方便拆分
- *
- * @param inputStream
- * @param filePath
- */
- public static void saveInputStreamToFile(InputStream inputStream, String filePath) {
- // 使用try-with-resources自动关闭流
- try (FileOutputStream outputStream = new FileOutputStream(new File(filePath))) {
- byte[] buffer = new byte[1024];
- int length;
- // 读取输入流并写入到输出流
- while ((length = inputStream.read(buffer)) > 0) {
- outputStream.write(buffer, 0, length);
- }
- System.out.println("文件保存成功!");
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
复制代码 多张图片归并逻辑
- /**
- * 多张图片合并之后的逻辑
- * @param imagePath
- * @param desPath
- * @return
- */
- public static boolean mergeImage(String imagePath, String desPath,String sux) {
- try {
- File folder = new File(imagePath);
- // 包含文件前缀的文件 简单解决并发的问题
- File[] imageFiles = folder.listFiles((dir, name) ->
- (name.toLowerCase().endsWith(".png") || name.toLowerCase().endsWith(".jpg") && name.contains(sux)));
- if (imageFiles != null && imageFiles.length > 0) {
- int maxWidth = 0;
- int totalHeight = 0;
- // 预先计算最大宽度和总高度
- for (File imageFile : imageFiles) {
- BufferedImage image = ImageIO.read(imageFile);
- maxWidth = Math.max(maxWidth, image.getWidth());
- totalHeight += image.getHeight();
- image.flush(); // 尝试释放资源
- }
- // 创建合并后的图片,仅初始化一次
- BufferedImage mergedImage = new BufferedImage(maxWidth, totalHeight, BufferedImage.TYPE_INT_ARGB);
- Graphics2D g2d = mergedImage.createGraphics();
- int currentY = 0;
- for (File imageFile : imageFiles) {
- BufferedImage image = ImageIO.read(imageFile);
- g2d.drawImage(image, 0, currentY, null);
- currentY += image.getHeight();
- image.flush(); // 处理完后释放当前图片资源
- }
- g2d.dispose();
- // 保存合并后的图片
- ImageIO.write(mergedImage, "PNG", new File(desPath));
- System.out.println("图片合并完成!");
- for (File file : imageFiles){
- if (file.exists()) {
- if (file.delete()) {
- System.out.println("文件 " + file.getName() + " 已被删除");
- } else {
- System.out.println("无法删除文件 " + file.getName());
- }
- } else {
- System.out.println("文件 " + file.getName() + " 不存在");
- }
- }
- } else {
- System.out.println("输入文件夹中没有图片文件!");
- }
- } catch (IOException e) {
- e.printStackTrace();
- System.out.println("图片合并失败: " + e.getMessage());
- }
- return true;
- }
复制代码 新建控制器PdfApi.java
用来接收小步伐调用传递过来的参数,需要判断传递过来的文件是否为图片格式,然后调用转换方法即可。
- /**
- * pdf转图片 多页转一张图
- * @param uploadFile
- * @return
- * @throws IOException
- */
- @PostMapping("pdfconvertimage")
- public String upload(@RequestPart("file") MultipartFile uploadFile) throws IOException {
- if (null == uploadFile) {
- return null;
- }
- // BMP、JPG、JPEG、PNG、GIF
- String fileName = uploadFile.getOriginalFilename().toLowerCase();
- if (!fileName.endsWith(".pdf")) {
- return null;
- }
- //String image= PdfUtils.pdf(uploadFile.getInputStream(),Integer.valueOf(type));
- String image= PdfUtils.pdfToPng(uploadFile.getInputStream(),fileName);
- // 返回响应实体
- return image;
- }
复制代码- [/code]
- [size=3]1.3 后端接口摆设[/size]
- 由于微信小步伐调用第三方接口需要https域名形式,以是接口开发完成后,需要摆设到云服务器,然后申请域名、申请SSL证书,确保接口可以通过https域名正常访问。而且在微信小步伐开发设置配置request正当域名白名单,包管接口可以调通。
-
- [align=center][img=1080,242]https://img-blog.csdnimg.cn/img_convert/74183d95edcf74ba5e44aff19ad9123f.png[/img][/align]
-
- [size=3]1.4 微信小步伐前端页面开发[/size]
- 打开微信开发者工具,然后微信小步伐管理员扫码登录自己的微信小步伐。这里主要给大家贴出主要的代码以及实现思绪。具体界面如下:
- 上传方式:支持微信会话文件上传、直接输入PDF文件的URL,转换成功后可以点击下载按钮进行下载图片。
-
- [align=center][img=369,627]https://img-blog.csdnimg.cn/img_convert/7a82d097e6be78587547857dbf7f3b49.png[/img][/align]
- [b]wxml文件代码如下:[/b]
- [code]
- <view style="text-align: center;">
- <image style="width: 98%;" src="推广图片"></image>
- </view>
- <view class="selectSection">
- <text class="textmag">上传方式:</text>
- <radio-group bindchange="radioChange" class="radio-group">
- <label class="radio" wx:for="{{direction}}" wx:key="i">
- <icon class="radioIcon {{item.checked?'actIcon':''}}"></icon>
- <radio checked="{{item.checked}}" value="{{item.name}}"></radio>{{item.value}}
- </label>
- </radio-group>
- </view>
- <view class="container">
- <view wx:if="{{directionType==1}}" class="item"> <button style="width: 120px;" class="butss" bindtap="chooseFile">上传pdf文件</button></view>
- <view wx:if="{{directionType==2}}" class="item"> <button style="width: 120px;" class="butss" bindtap="chooseFileNew">生成图片</button></view>
- <view class="item"> <button style="width: 90px;" class="butss" bindtap="saveTap">下载</button></view>
- <view class="item"> <button style="width: 90px;" class="butss" bindtap="clearTap">清空</button></view>
- </view>
- <view style="padding: 20px;">
- <span style="color: red;font-size: 12px;">温馨提示:目前支持10页以内的pdf文件转换</span>
- </view>
- <view>
- <textarea auto-height bindinput="handleInput" class="input-content" value="{{uploadUrl}}" placeholder="请输入pdf文件url" wx:if="{{directionType==2}}"></textarea>
- </view><view class="instruction">
- <span style="color: black;padding-left: 10px;">结果文件:{{data}}</span>
- </view>
复制代码
js主要代码:
- // 选择微信会话文件 然后直接调用上传接口
- chooseFile: function () {
- var that = this;
- wx.showLoading({
- title: '图片上传处理中,请稍后...',
- });
- wx.chooseMessageFile({
- count: 1,
- type: 'file',
- extension: ['pdf'], // 限定选择的文件格式为.doc, .docx, .pdf
- success: function (res) {
- const tempFilePath = res.tempFiles[0].path;
- if (res.tempFiles[0].size > 10 * 1024 * 1024) { // 限定文件大小为2MB
- wx.showToast({
- title: '文件大小超过限制,请选择小于10MB的文件',
- icon: 'none'
- });
- return;
- }
- that.setData({
- pdfPath: tempFilePath })wx.uploadFile({
- url: '后端接口API',
- filePath: tempFilePath,
- formData: {
- },
- name: 'file',
- success: function (res) {
- if (res.statusCode == "200") {
- that.setData({
- imageUrl: res.data,// 直接可以访问的url
- data: res.data
- });
- wx.showToast({
- title: '转换成功',
- icon: 'success',
- duration: 2000
- });
- } else {
- wx.showToast({
- title: '转换失败,请联系管理员',
- icon: 'none',
- duration: 2000
- });
- }
- },
- fail: function (res) {
- wx.showToast({
- title: '上传失败',
- icon: 'none',
- duration: 2000
- });
- }
- });
- },
- fail: function (res) {
- console.error('选择文件失败', res);
- wx.showToast({
- title: '选择文件失败',
- icon: 'none',
- duration: 2000
- });
- }
- });
- },
-
- // 下载按钮事件
- saveTap: function () {
- if (this.data.imageUrl) {
- wx.downloadFile({
- url: this.data.imageUrl,
- success: function (res) {
- if (res.statusCode === 200) {
- var filePath = res.tempFilePath;
- // 调用保存图片方法
- wx.saveImageToPhotosAlbum({
- filePath: filePath,
- success: function (res) {
- wx.showToast({
- title: '保存成功',
- icon: 'success',
- duration: 2000
- });
- },
- fail: function (err) {
- console.error(err);
- wx.showToast({
- title: '保存失败',
- icon: 'none',
- duration: 2000
- });
- }
- });
- }
- },
- fail: function (err) {
- console.error(err);
- wx.showToast({
- title: '下载失败',
- icon: 'none',
- duration: 2000
- });
- }
- });
- } else {
- wx.showToast({
- title: '请先上传pdf文件,转换成功后再保存',
- icon: 'none',
- duration: 2000
- });
- }
- },
复制代码
1.5 运行效果
选择pdf文件上传
转换成功之后的结果文件如下:
然后可以点击下载按钮下载图片文件。整体转还原度还是很高的。
1.6 小步伐摆设上线
该步骤对于小步伐开发的朋友来说,还黑白常简单的,这里就不外多先容了,大家有问题的话,接待沟通交换!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |