做网站建设的公司有哪些,wordpress it,旅游网站网页设计,图书网站建设源码相关链接
目录参考文章#xff1a;pdf转图片(apache pdfbox)参考文章#xff1a;GUI界面-awt参考文章#xff1a;jar包转exe(exe4j)参考文章#xff1a;IDEA导入GIT项目参考文章#xff1a;IDEA中使用Gitee管理代码gitee项目链接#xff1a;pdf_2_image网盘地址#xf…相关链接
目录参考文章pdf转图片(apache pdfbox)参考文章GUI界面-awt参考文章jar包转exe(exe4j)参考文章IDEA导入GIT项目参考文章IDEA中使用Gitee管理代码gitee项目链接pdf_2_image网盘地址.jar文件提取码: ppwr网盘地址.exe文件提取码jp3y 背景介绍 最近做标书涉及到很多批量pdf文件要转图片再将插入word的使用场景大概几千份本着能省就省的原则下载了四五个app基本都是要收费永久会员50~600不等不付费会受到各种功能限制禁用批量功能、单个文件页数限制。 自己尝试写个小工具由于之前做的小工具都是打成jar包只能在有jre环境的电脑上黑窗口操作。这次转为exe文件用到的GUI和exe4j属于新的尝试最终效果还比较满意。 开发流程 1.单个pdf转图片Apache PDFbox 开源包实现pdf转单个图片。2.批量pdf转图片结合上面功能实现批量转文件。3.GUI可视化界面awt设计思路类似于大学的vb编程课实现界面操作。4.exe可执行文件exe4j可以不安装jre环境windows系统下双击即可运行。 两处避坑 1. macos M1芯片下载后使用不了换了台windows才运行成功。 2. 下载时默认exe4j 9.0应该是指对应的版本为java9及以上。我的项目使用jdk8就要下载exe4j 8.0版本否则会卡在其中一步点下一步没有反应进行不下去。 卡住的位置 5.自适应写死分辨率容易导致在分辨率较高的屏幕下窗口非常小通过获取屏幕尺寸按比例计算各个组件坐标、长宽实现自适应大小。 功能示例 1.设置dpi清晰度100~6002.图片格式jpg和png3.自动遍历子目录按照 原文件名_序号 格式生成对应图片 源码
pom.xml
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactIdpdf_2_image/artifactIdversion1.0-SNAPSHOT/versionpropertiesmaven.compiler.source8/maven.compiler.sourcemaven.compiler.target8/maven.compiler.target/propertiesdependencies!--pdf2jpg--dependencygroupIdorg.apache.pdfbox/groupIdartifactIdfontbox/artifactIdversion2.0.9/version/dependency!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox --dependencygroupIdorg.apache.pdfbox/groupIdartifactIdpdfbox/artifactIdversion2.0.9/version/dependency!-- https://mvnrepository.com/artifact/commons-logging/commons-logging --dependencygroupIdcommons-logging/groupIdartifactIdcommons-logging/artifactIdversion1.2/version/dependency/dependenciesbuildpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-shade-plugin/artifactIdversion1.4/versionexecutionsexecutionphasepackage/phasegoalsgoalshade/goal/goalsconfigurationfiltersfilterartifact*:*/artifactexcludesexcludeMETA-INF/*.SF/excludeexcludeMETA-INF/*.DSA/excludeexcludeMETA-INF/*.RSA/exclude/excludes/filter/filterstransformerstransformerimplementationorg.apache.maven.plugins.shade.resource.ManifestResourceTransformer!-- 程序主入口 --mainClasscom.groupies.Pdf2ImageIteratorWindowsAdaptive/mainClass/transformertransformerimplementationorg.apache.maven.plugins.shade.resource.AppendingTransformerresourceMETA-INF/spring.handlers/resource/transformertransformerimplementationorg.apache.maven.plugins.shade.resource.AppendingTransformerresourceMETA-INF/spring.schemas/resource/transformer/transformers/configuration/execution/executions/pluginplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdversion2.3.1/versionconfigurationsource1.8/sourcetarget1.8/targetencodingutf-8/encoding/configuration/plugin/plugins/build
/projectPdf2ImageIteratorWindowsAdaptive
package com.groupies;import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;/*** author GroupiesM* date 2023/11/30* version 1.2* introduction pdf转图片工具类awt可视化界面会自动遍历所有子目录窗口大小自适应*/
public class Pdf2ImageIteratorWindowsAdaptive {//公共变量static String filePath;//基础路径static String fileName;//文件名称//用户输入static Integer dpiInput;//dpi清晰度static String imageTypeInput;//图片类型static File fileUrl;//文件目录//循环相关static Integer taskCount 0;//任务数量static Integer imageCount 0;//图片数量//主体static Frame frame new Frame(pdf转图片小工具 -- by GroupiesM);//控制台static TextArea textAreaConsole new TextArea();static StringBuffer sb new StringBuffer();//按比例获取尺寸static Toolkit toolkit Toolkit.getDefaultToolkit();static int frameWidth toolkit.getScreenSize().width * 2 / 5;//宽static int frameHeight toolkit.getScreenSize().height * 19 / 20;//高static int leftEdge frameWidth / 10;//左边距static int elementWidth frameWidth * 4 / 5;//组件宽度static int elementHeight frameWidth / 20;//组件宽度//字体static Font titleFontLabel new Font(黑体, Font.BOLD, Math.max((frameWidth / 55), 12));//标签样式static Font bodyFontLabel new Font(宋体, Font.PLAIN, Math.max((frameWidth / 55), 12));//标签样式/*** param args* introduction 程序入口*/public static void main(String[] args) {textAreaConsole.setText(介绍\nhttps://blog.csdn.net/qq_43529621/article/details/134758957);initGUI();}/*** param folder* introduction 遍历目录中的所有pdf、子目录中的所有pdf发现pdf文件则调用pdf2png方法转换pdf文件为png*/public static void traverseFolder(File folder) {if (folder.isDirectory()) {File[] files folder.listFiles();if (files ! null) {for (File file : files) {if (file.isDirectory()) {traverseFolder(file); // 递归遍历子文件夹} else if (file.getAbsolutePath().endsWith(.pdf)) {//如果是pdf文件转图片filePath folder.getAbsolutePath();//文件目录fileName file.getName();//文件名sb.append(------------Task taskCount ------------\r\n);sb.append(目录 folder.getAbsolutePath() \r\n);sb.append(文件 file.getAbsolutePath() \r\n);textAreaConsole.setText(sb.toString());System.out.println(------------Task taskCount ------------);System.out.println(目录 folder.getAbsolutePath());System.out.println(文件 file.getAbsolutePath());try {pdf2png(filePath, filePath, fileName, imageTypeInput);} catch (Exception e) {//e.printStackTrace();sb.append(e.getMessage() \r\n);textAreaConsole.setText(sb.toString());}}}}} else {System.out.println(路径有误请重新输入);}}/*** introduction 使用pdfbox将整个pdf转换成图片* param sourceDirectory* param targetDirectory* param filename* param type 图片类型 png 和jpg* throws Exception*/public static void pdf2png(String sourceDirectory, String targetDirectory, String filename, String type) throws Exception {long startTime System.currentTimeMillis();// 将文件地址和文件名拼接成路径 注意线上环境不能使用\\拼接File file new File(sourceDirectory / filename);try {// 写入文件PDDocument doc PDDocument.load(file);PDFRenderer renderer new PDFRenderer(doc);int pageCount doc.getNumberOfPages();for (int i 0; i pageCount; i) {// dpi为144越高越清晰转换越慢BufferedImage image renderer.renderImageWithDPI(i, dpiInput); // Windows native DPI// 将图片写出到该路径下sb.append(图片 imageCount targetDirectory / filename.replace(.pdf, ) _ (i 1) . type \r\n);textAreaConsole.setText(sb.toString());System.out.println(图片 imageCount targetDirectory / filename.replace(.pdf, ) _ (i 1) . type);File imageTarget new File(targetDirectory / filename.replace(.pdf, ) _ (i 1) . type);//覆盖写文件ImageIO.write(image, type, imageTarget);}long endTime System.currentTimeMillis();//结束时间doc.close();//关流否则会报异常 Warning: You did not close a PDF Documentsb.append(共耗时 ((endTime - startTime) / 1000.0) 秒\r\n);textAreaConsole.setText(sb.toString());System.out.println(共耗时 ((endTime - startTime) / 1000.0) 秒); //转化用时} catch (IOException e) {e.printStackTrace();sb.append(e.getMessage());textAreaConsole.setText(sb.toString());}}/*** introduction 初始化GUI页面*/public static void initGUI() {//todo 0.创建窗口Frameframe.setVisible(true);frame.setSize(frameWidth, frameWidth * 203 / 200);//设置大小frame.setBackground(new Color(88, 87, 86));//窗口背景色frame.setLayout(null);//todo 1.1 《dpi》标签Label labelDpi new Label( 一、dpi分辨率越高越清晰转换越慢);labelDpi.setBounds(leftEdge, elementHeight * 3 / 2, elementWidth, elementHeight);//设置位置、大小labelDpi.setBackground(Color.darkGray);//背景色labelDpi.setForeground(Color.WHITE);//字体颜色labelDpi.setFont(titleFontLabel);frame.add(labelDpi);//给窗口添加组件//todo 1.2 《dpi》滚动条Scrollbar scrollbarDpi new Scrollbar(Scrollbar.HORIZONTAL, 144, elementHeight, 100, 600 elementHeight); //构造一个具有指定方向初始值粗细、最小值、最大值的新滚动条scrollbarDpi.setBounds(leftEdge * 3 / 2, elementHeight * 27 / 10, elementWidth / 2, elementHeight * 2 / 3);//设置位置、大小frame.add(scrollbarDpi);//给窗口添加组件//todo 1.3《dpi回显》标签Label labelDpiValue new Label(\t\t144);labelDpiValue.setBounds(leftEdge * 3 / 2 elementWidth / 2, elementHeight * 27 / 10, leftEdge, elementHeight * 2 / 3);//设置位置、大小labelDpiValue.setForeground(Color.WHITE);//字体颜色labelDpiValue.setBackground(Color.darkGray);//字体颜色labelDpiValue.setFont(bodyFontLabel);frame.add(labelDpiValue);//给窗口添加组件//todo 1.4《dpi》滚动条背景Label labelDpiBackGround new Label();labelDpiBackGround.setBounds(leftEdge, elementHeight * 5 / 2, elementWidth, elementHeight * 6 / 5);//设置大小labelDpiBackGround.setBackground(Color.darkGray);//背景色frame.add(labelDpiBackGround);//给窗口添加组件//todo 2.1《转换类型》标签Label labelImageType new Label( 二、图片类型jpg:有损压缩png:无损压缩);labelImageType.setBounds(leftEdge, elementHeight * 21 / 5, elementWidth, elementHeight);//设置大小labelImageType.setBackground(Color.darkGray);//设置标签背景色labelImageType.setForeground(Color.white);//设置标签背景色labelImageType.setFont(titleFontLabel);frame.add(labelImageType);//add()给窗口添加标签//todo 2.2《转换类型》单选框CheckboxGroup boxImageType new CheckboxGroup();Checkbox ck1 new Checkbox(jpg, boxImageType, true);Checkbox ck2 new Checkbox(png, boxImageType, false);ck1.setBounds(leftEdge * 3 / 2, elementHeight * 26 / 5, leftEdge * 3 / 2, elementHeight);ck2.setBounds(leftEdge * 6 / 2, elementHeight * 26 / 5, leftEdge * 3 / 2, elementHeight);ck1.setForeground(Color.white);ck2.setForeground(Color.white);ck1.setBackground(Color.darkGray);ck2.setBackground(Color.darkGray);ck1.setFont(bodyFontLabel);ck2.setFont(bodyFontLabel);frame.add(ck1);//给窗口添加组件frame.add(ck2);//给窗口添加组件//todo 2.3《转换类型》背景Label labelImageTypeBackGround new Label();labelImageTypeBackGround.setBounds(leftEdge, elementHeight * 26 / 5, elementWidth, elementHeight * 6 / 5);//设置大小labelImageTypeBackGround.setBackground(Color.darkGray);//背景色frame.add(labelImageTypeBackGround);//给窗口添加组件//todo 3.1《目录》标签LabelLabel labelUrl new Label( 三、文件路径例如C:\\Users\\GroupiesM\\Desktop);labelUrl.setBounds(leftEdge, elementHeight * 7, elementWidth, elementHeight);//设置大小labelUrl.setBackground(Color.darkGray);//背景色labelUrl.setForeground(Color.WHITE);//字体颜色labelUrl.setFont(titleFontLabel);frame.add(labelUrl);//给窗口添加组件//todo 3.2《目录》输入框TextField textUrl new TextField(elementHeight);textUrl.setText(C:\\Users\\GroupiesM\\Desktop);textUrl.setFont(bodyFontLabel);textUrl.setBounds(leftEdge, elementHeight * 8, elementWidth, elementHeight);frame.add(textUrl);//给窗口添加组件//todo 4《清空》按钮Button buttonClean new Button(清空);//创建按钮buttonClean.setBounds(leftEdge * 2, elementHeight * 19 / 2, leftEdge * 7 / 5, elementHeight * 7 / 5);//设置位置buttonClean.setFont(titleFontLabel);frame.add(buttonClean);//给窗口添加组件//todo 5《转换》按钮Button buttonTransform new Button(转换);//创建按钮buttonTransform.setBounds(leftEdge * 22 / 5, elementHeight * 19 / 2, leftEdge * 7 / 5, elementHeight * 7 / 5);//设置位置buttonTransform.setFont(titleFontLabel);frame.add(buttonTransform);//给窗口添加组件//todo 6《退出》按钮Button buttonExit new Button(退出);//创建按钮buttonExit.setBounds(leftEdge * 34 / 5, elementHeight * 19 / 2, leftEdge * 7 / 5, elementHeight * 7 / 5);//设置位置buttonExit.setFont(titleFontLabel);frame.add(buttonExit);//给窗口添加组件//todo 7《控制台》textAreaConsole.setBounds(leftEdge, elementHeight * 113 / 10, elementWidth, elementHeight * 9);//设置大小textAreaConsole.setBackground(Color.white);//背景色textAreaConsole.setForeground(Color.black);//背景色textAreaConsole.setFont(bodyFontLabel);frame.add(textAreaConsole);//给窗口添加组件//todo 7.1《dpi滚动条》触发动作scrollbarDpi.addAdjustmentListener(e - labelDpiValue.setText(String.valueOf(\t\t scrollbarDpi.getValue())));//回显滚动条//todo 7.2 《清空》触发动作buttonClean.addActionListener(actionEvent - textUrl.setText(\b));//清空输入框//todo 7.3 《转换》触发动作buttonTransform.addActionListener(actionEvent - startTransform(scrollbarDpi, boxImageType, textUrl));//开始转换并校验//todo 7.4 《退出》触发动作buttonExit.addActionListener(Pdf2ImageIteratorWindowsAdaptive::actionPerformed);//frame.pack();}/*** introduction 开始转换初始化参数校验文件目录是否存在* param scrollbarDpi dpi清晰度* param group 图片类型单选框* param textUrl 文件目录*/public static void startTransform(Scrollbar scrollbarDpi, CheckboxGroup group, TextField textUrl) {dpiInput scrollbarDpi.getValue();//设置dpiimageTypeInput group.getSelectedCheckbox().getLabel();//设置图片类型fileUrl new File(textUrl.getText().trim());//创建文件//如果目录不存在不执行指令if (!fileUrl.exists()) {textUrl.setForeground(Color.red);if (!textUrl.getText().trim().endsWith((路径不存在))) textUrl.setText(textUrl.getText().trim() (路径不存在));textUrl.selectAll();return;}//校验通过textUrl.setForeground(Color.black);//初始化参数sb new StringBuffer();taskCount 0;//任务数量imageCount 0;//图片数量//开始转换traverseFolder(fileUrl);}/*** introduction 退出按钮, 监听* param e*/private static void actionPerformed(ActionEvent e) {sb initSB();textAreaConsole.setText(....................正在退出.....................\n \n sb.toString());try {Thread.sleep(1600);} catch (InterruptedException ex) {ex.printStackTrace();}sb initSB();textAreaConsole.setText(....................正在退出.....................\n \n sb.reverse().toString());try {Thread.sleep(1300);} catch (InterruptedException ex) {ex.printStackTrace();}System.exit(0);}/*** introduction 退出程序-控制台* return StringBuffer*/public static StringBuffer initSB() {sb new StringBuffer();sb.append( _oo0oo_ \n);sb.append( o8888888o \n);sb.append( 88” . “88 \n);sb.append( ( |- _ - | ) \n);sb.append( O \\ / O \n);sb.append( __/ ‘---’ \\__ \n);sb.append( \\| |/ \n);sb.append( / \\\\||| : |||// \\ \n);sb.append( / _||||| -卍- |||||_ \\ \n);sb.append( | |\\\\\\ - /// |_ \\ \n);sb.append( | \\_| \\---/ |_/ | \n);sb.append( \\ ,-\\__ - __/- , / \n);sb.append( ___. . /--.--\\ . .___ \n);sb.append( .”“ ‘.___\\_|_/___. ”“. \n);sb.append( | | : -\\.:\\ _ / : ./ - : | | \n);sb.append( \\ \\ _. \\_ __\\ /__ _/ , - / / \n);sb.append( -.___.___ \\____//___.- ___.- \n);sb.append( ---- \n);sb.append( \n);return sb;}
}23/12/3 M