一: 需求详情:
公司需要存储合同文件, 用户上传 word 文档的合同, 通过 openOffice 去把 word 转换为 pdf, 再把 pdf 转换为图片格式, 并分别存储. 因为 openOffice 的转换需要耗费挺大的内存, 所以设计为 task 任务, 凌晨自动转换.
记录本次需求完成的时候遇到的问题.
二: 过程
1: 本地环境编码(windows)
第一步: 因为是本地环境的编码而且是 Windows 环境, 所以从安装 openOffice 开始, 到启动服务并没有遇到难题.
第二步: 转换所需要的工具包;
- <dependency>
- <groupId>commonscli</groupId>
- <artifactId>commonscli</artifactId>
- <version>1.2</version>
- </dependency>
- <dependency>
- <groupId>commonsio</groupId>
- <artifactId>commonsio</artifactId>
- <version>1.4</version>
- </dependency>
- <dependency>
- <groupId>org.openoffice</groupId>
- <artifactId>juh</artifactId>
- <version>3.0.1</version>
- </dependency>
- <dependency>
- <groupId>org.openoffice</groupId>
- <artifactId>jurt</artifactId>
- <version>3.0.1</version>
- </dependency>
- <dependency>
- <groupId>org.openoffice</groupId>
- <artifactId>ridl</artifactId>
- <version>3.0.1</version>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4japi</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4jjdk14</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.openoffice</groupId>
- <artifactId>unoil</artifactId>
- <version>3.0.1</version>
- </dependency>
- <dependency>
- <groupId>com.thoughtworks.xstream</groupId>
- <artifactId>xstream</artifactId>
- <version>1.3.1</version>
- </dependency>
- <dependency>
- <groupId>org.apache.pdfbox</groupId>
- <artifactId>fontbox</artifactId>
- <version>2.0.8</version>
- </dependency>
- <dependency>
- <groupId>org.apache.pdfbox</groupId>
- <artifactId>pdfbox</artifactId>
- <version>2.0.8</version>
- </dependency>
问题 1: 在这里遇到了第一个问题, 就是在 maven 的中央仓库找不到关键的依赖 jar 包的问题.
jodconvertercli 这个 jar 包中央仓库找不到 jar 包依赖, jodconverter 版本才到 2.2.1(这个版本之前的不能支持 docx 格式转换, 2.2.2 及以后才开始支持.)
然后和大牛商量, 加入到公司内网自己的 maven 仓库.
第三步: 工具类
- /**
- * author GH
- * 输入文件
- * 输出文件
- */
- public class WordToPdf {//word 转 pdf
- public static void docToPdf(File inputFile, File outputFile){
- OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
- try{
- connection.connect();
- DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
- converter.convert(inputFile, outputFile);
- }catch(ConnectException cex){
- cex.printStackTrace();
- }finally{
- if(connection!=null){
- connection.disconnect();
- connection = null;
- }
- }
- }
- }
- /**
- * author GH
- * 参数 1: 要装换的 pdf 位置
- * 参数 2: 转换后的图片存放位置
- * 参数 3: 中间要拼接的名字
- * return: 转换后的 img 名字集合
- */
- public class PdfToImage {//pdf 转 img
- public static List<String> pdfToImagePath(String srcFile,String contractFromSrc,String name){
- List<String> list = new ArrayList<>();
- String imagePath;
- File file = new File(srcFile);
- try {
- File f = new File(contractFromSrc);
- if(!f.exists()){
- f.mkdir();
- }
- PDDocument doc = PDDocument.load(file);
- PDFRenderer renderer = new PDFRenderer(doc);
- int pageCount = doc.getNumberOfPages();
- for(int i=0; i<pageCount; i++){
- // 方式 1, 第二个参数是设置缩放比(即像素)
- // BufferedImage image = renderer.renderImageWithDPI(i, 296);
- // 方式 2, 第二个参数是设置缩放比(即像素)
- BufferedImage image = renderer.renderImage(i, 2f); // 第二个参数越大生成图片分辨率越高, 转换时间也就越长
- imagePath = contractFromSrc+name+""+i +".jpg";
- ImageIO.write(image, "PNG", new File(imagePath));
- list.add(name+""+i +".jpg");
- }
- doc.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return list;
- }
- }
第四步: 编码
首先从数据库读取没有转换过的集合, 循环下载 oss 对象存储文件到指定临时文件夹.
通过工具类转换下载的 word 为 pdf, 录入数据 pdf 记录, 上传 oss 对象 pdf 图片.
通过工具类转换得到的 pdf 图片, 录入数据路图片记录, 上传转换得到的 img 图片.
try catch 捕捉异常, 有异常就回滚数据库, 删除 oss 对象上传的文件.
修改 word 的转换状态为已转换.
问题 2: 因为到最后测试环境和生产环境都是 Linux 系统的, 因为涉及到文件的操作, 但是 Linux 和 Windows 的文件路径是不一样的, 例如: Windows 文件路径为(C:\tmp\test.txt)Linux 则为(/tmp/test.txt)
因此 采用这种方式
- public final static String ConvertTmpUrl="C:"+File.separator+"temp"+File.separator+"contractToImg"+File.separator;// 进行 wordimg 转换的时候的暂时存放路径 window
- public final static String ConvertTmpUrl2=File.separator+"tmp"+File.separator+"contractToImg"+File.separator;// 进行 wordimg 转换的时候的暂时存放路径 linux
File.separator 与系统有关的默认名称分隔符, 为了方便, 它被表示为一个字符串 在 Linux 此字段的值为 '/' Windows 为'\'
第五步: 本地测试, 没有问题.
2: 测试环境测试(windows)
问题 3: 在 Linux 环境下 word 转换 word 中文出现乱码 空白, 导致的原因是 Linux 缺少中文字体编码.
解决方法:
步骤 1: 创建路径.
在 centos 的 / usr/java/jdk1.8.091/jre/lib/fonts 下新建路径: fallback.
步骤 2: 上传字体.
将字体: simhei.ttf 黑体, simsun.ttc 宋体 (windows 下通过 everything 找下) 上传至 / usr/java/jdk1.8.091/jre/lib/fonts/fallback 路径下.
步骤 3: 查看系统字体文件路径.
查看方案:
- [root80ec6 fallback]# cat /etc/fonts/fonts.conf
- <! Font directory list >
- <dir
- >/usr/share/fonts
- </dir>
- <dir
- >/usr/share/X11/fonts/Type1
- </dir
- >
- <dir
- >/usr/share/X11/fonts/TTF
- </dir
- >
- <dir
- >/usr/local/share/fonts
- </dir>
- <dir
- >~/.fonts
- </dir>
步骤 4: 字体拷贝.
将 /usr/java/jdk1.8.091/jre/lib/fonts 的全部内容, 拷贝到步骤 3 查看的路径下, 我的字体路径为:/usr/share/fonts.
步骤 5: 更新缓存
执行命令: fccache
步骤 6:kill 掉 openoffice 进程.
- [root80ec6 fonts]# ps ef | grep openoffice
- root 3045 3031 0 06:19 pts/1 00:00:03 /opt/openoffice4/program/soffice.bin headless accept=socket,host=127.0.0.1,port=8100;urp; nofirststartwizard
执行 kill:kill 9 3045
步骤 7: 重启后台运行 openoffice.
[roota3cf78780ec6 openoffice4]# soffice headless accept="socket,host=127.0.0.1,port=8100;urp;" nofirststartwizard &
3: 测试环境和生产环境内核不一样, 安装的安装包不一样.
测试环境的安装的是 deb 文件, 使用 dpkg 命令安装所有的 deb 文件, 启动服务就能使用.
生产环境的是 dpkg 命令找不到. 改换安装 prm 文件, 执行安装之后, 竟然启动不了, 查找原因之后尽然是没有安装完, RPMS 目录下有 desktopintegration 文件夹, 进入到 desktopintegration 目录, 里面有四个 rpm 文件, 选择相应的安装即可, 这里我选择的是 redhat 版本.
执行 rpm ivh openoffice4.1.5redhatmenus4.1.59789.noarch.rpm
来源: https://www.cnblogs.com/GH0522/p/9619435.html