Java 将word转为PDF的三种方式和处理在服务器上下载后乱码的格式

我这边是因为业务需要将之前导出的word文档转换为PDF文件,然后页面预览下载这样的情况。之前导出word文档又不是我做的,所以为了不影响业务,只是将最后在输出流时转换成了PDF,当时本地调用没什么问题,一切正常,后面发布测试环境使用时才发现,导出时PDF文件内容乱码了,中文没有一个显示的。
这里记录下当时遇到的问题和解决方式:

1:解决中文不显示,乱码处理情况

我这里是使用的POI进行的转换,直接将word转换成PDF,转换方式放在后面。
当时转换后的PDF长这样:
在这里插入图片描述
正常格式下是有很多中文说明的。下面就是处理方式:
当时就想到了是服务器上不支持中文,所以百度了一圈,果然是,然后就开始加中文字体:
Linux 服务器上字体目录是在:/user/share/fonts 下的
1:在/user/share/fonts 下创建自己的文件夹字体,我这里是my-fonts
在这里插入图片描述
如果这里找不到的话,可以使用命令 fc-list 查看一下有没有,如果没有或者出现该命令不可用的情况,那就需要先安装基础字体:使用命令:yum -y install fontconfig ,完成之后就能看到/user/share/fonts 了

2:找到Windows中的字体,将字体上传到这个 my-fonts中
在这里插入图片描述
这里面有很多字体,我们需要的是中文字体,可以选择性上传,选择需要的中文字体上传,比如宋体,要和你文件模板中字体一致就行。上传到my-fonts文件夹下

3:安装
接着根据当前目录下的字体建立scale文件,
切换到my-fonts目录下执行命令:mkfontscale
若提示mkfontscale command not found,则运行yum install mkfontscale

接着建立dir文件:mkfontdir
使用命令:vi /etc/fonts/fonts.conf 修改配置文件,添加:<dir>/usr/share/fonts/my-fonts</dir>
添加后:
在这里插入图片描述

然后运行:fc-cache
fc-list #查看字体列表

4:赋予权限
chmod 777 /usr/share/fonts/my-fonts
chmod 755 /usr/share/fonts/my-fonts/*

使用命令查看: fc-list :lang=zh

2:Word转PDF实现的几种方式

1:使用POI的方式将word转换为PDF
引入依赖:

<dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.poi.xwpf.converter.pdf-gae</artifactId><version>2.0.1</version>
</dependency>

在关闭流之前添加并修改reponse中.docx为.pdf

response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode("日报-"+datetime+".pdf", "UTF-8"));
//转为PDF
PdfOptions options = PdfOptions.create();
PdfConverter.getInstance().convert(document, outStream, options);
//下面再是转word里面最后的代码,关闭流

2:使用aspose.words的Document方式将word转换为PDF
1:下载jar包:jar包下载
2:将jar包放入项目中resources目录下的lib文件夹中:
在这里插入图片描述
3:将jar包转为library
在这里插入图片描述
转换后就会出现上面图中箭头处的样子可以打开。

4:引入jar包依赖:

<dependency><groupId>com.aspose.words</groupId><artifactId>aspose-words</artifactId><version>15.8.0</version><scope>system</scope><systemPath>${project.basedir}/src/main/resources/lib/aspose-words-15.8.0-jdk16.jar</systemPath>
</dependency>

在打包的依赖中添加:

			<plugin><configuration><includeSystemScope>true</includeSystemScope></configuration></plugin>

5:转换

String s = "<License><Data><Products><Product>Aspose.Total for Java</Product><Product>Aspose.Words for Java</Product></Products><EditionType>Enterprise</EditionType><SubscriptionExpiry>20991231</SubscriptionExpiry><LicenseExpiry>20991231</LicenseExpiry><SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber></Data><Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature></License>";//去除水印ByteArrayInputStream is = new ByteArrayInputStream(s.getBytes());License license = new License();license.setLicense(is);//将XWPFDocument转换为InputStreamByteArrayOutputStream b = new ByteArrayOutputStream();//这里的document=XWPFDocument document,在下面的word转换中document.write(b);InputStream inputStream = new ByteArrayInputStream(b.toByteArray());//这里的Document 的引入是//import com.aspose.words.Document;//import com.aspose.words.License;//import com.aspose.words.SaveFormat;Document doc = new Document(inputStream);doc.save(outStream, SaveFormat.PDF);b.close();inputStream.close();//下面再是转word里面最后的代码,关闭流

3:使用documents4j 的方式将word转换为PDF

1:引入依赖:

        <!-- word 转 pdf   通过documents4j实现    --><dependency><groupId>com.documents4j</groupId><artifactId>documents4j-local</artifactId><version>1.0.3</version></dependency><dependency><groupId>com.documents4j</groupId><artifactId>documents4j-transformer-msoffice-word</artifactId><version>1.0.3</version></dependency>

2:转换如下:

		//将XWPFDocument转换为InputStreamByteArrayOutputStream b = new ByteArrayOutputStream();//这里的document=XWPFDocument document,在下面的word转换中document.write(b);InputStream docxInputStream = new ByteArrayInputStream(b.toByteArray());//下面的引入类为://import com.documents4j.api.DocumentType;//import com.documents4j.api.IConverter;//import com.documents4j.job.LocalConverter;IConverter converter = LocalConverter.builder().build();boolean execute = converter.convert(docxInputStream).as(DocumentType.DOCX).to(outStream).as(DocumentType.PDF).schedule().get();b.close();docxInputStream.close();

3:这里之前转换word方式记录如下

1:制作word模板,将需要转换的数值写成了${变量名}。
在这里插入图片描述
2:转换

//模板文件的地址
String filePath = "/usr/local/data/模板.docx";
//Map存储需要替换的值
Map<String, Object> map = new HashMap<>();
map.put("${date}", date);
map.put("${datetime}", datetime);
//写入
try {// 替换的的关键字存放到Set集合中Set<String> set = map.keySet();// 读取模板文档XWPFDocument document = new XWPFDocument(new FileInputStream(filePath ));/*** 替换段落中的指定文字*/// 读取文档中的段落,回车符为一个段落。// 同一个段落里面会被“:”等符号隔开为多个对象Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();while (itPara.hasNext()) {// 获取文档中当前的段落文字信息XWPFParagraph paragraph = (XWPFParagraph) itPara.next();List<XWPFRun> run = paragraph.getRuns();// 遍历段落文字对象for (int i = 0; i < run.size(); i++) {// 获取段落对象if (run.get(i) == null) {	//段落为空跳过continue;}String sectionItem = run.get(i).getText(run.get(i).getTextPosition());						 //段落内容//System.out.println("替换前 === "+sectionItem);// 遍历自定义表单关键字,替换Word文档中的内容Iterator<String> iterator = set.iterator();while (iterator.hasNext()) {// 当前关键字String key = iterator.next();// 替换内容sectionItem = sectionItem.replace(key, 	String.valueOf(map.get(key)));}//System.out.println(sectionItem);run.get(i).setText(sectionItem, 0);}}/*** 替换表格中的指定文字*///获取文档中所有的表格,每个表格是一个元素Iterator<XWPFTable> itTable = document.getTablesIterator();while (itTable.hasNext()) {XWPFTable table = (XWPFTable) itTable.next();   //获取表格内容int count = table.getNumberOfRows();    //表格的行数//遍历表格行的对象for (int i = 0; i < count; i++) {XWPFTableRow row = table.getRow(i);    //表格每行的内容List<XWPFTableCell> cells = row.getTableCells();   //每个单元格的内容//遍历表格的每行单元格对象for (int j = 0; j < cells.size(); j++) {XWPFTableCell cell = cells.get(j);	//获取每个单元格的内容List<XWPFParagraph> paragraphs = cell.getParagraphs();      //获取单元格里所有的段落for (XWPFParagraph paragraph : paragraphs) {//获取段落的内容List<XWPFRun> run = paragraph.getRuns();// 遍历段落文字对象for (int o = 0; o < run.size(); o++) {// 获取段落对象if (run.get(o) == null || run.get(o).equals("")) {continue;}String sectionItem = run.get(o).getText(run.get(o).getTextPosition());	//获取段落内容if (sectionItem == null || sectionItem.equals("")) {	//段落为空跳过continue;}//遍历自定义表单关键字,替换Word文档中表格单元格的内容for (String key : map.keySet()) {// 替换内容sectionItem = sectionItem.replace(key, String.valueOf(map.get(key)));run.get(o).setText(sectionItem, 0);}}}}}}SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");String datetime = sdf.format(new Date());response.setStatus(200);response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode("模板-"+datetime+".docx", "UTF-8"));response.setCharacterEncoding("utf8");OutputStream outStream = response.getOutputStream();//这里将插入转换成PDF的代码outStream.close();document.close();} catch (Exception e) {e.printStackTrace();}

上面就是别人之前业务场景中的转换word的代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/213658.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

flask web学习之flask与http(一)

文章目录 一、请求响应循环二、HTTP请求1. 请求报文2. request对象3. 在flask中处理请求3.1 路由匹配3.2 设置监听的http方法3.3 URL处理 三、请求钩子 一、请求响应循环 每一个web应用都包含这种处理方式&#xff0c;请求-响应循环&#xff1a;客户端发出请求&#xff0c;服务…

无参RCE [GXYCTF2019]禁止套娃1

打开题目 毫无思绪&#xff0c;先用御剑扫描一下 只能扫出index.php 我们尝试能不能用php伪协议读取flag php://filter/readconvert.base64-encode/resourceindex.php php://filter/readconvert.base64-encode/resourceflag.php 但是页面都回显了429 怀疑是不是源码泄露 用…

【HttpRunner】接口自动化测试框架

简介 2018年python开发者大会上&#xff0c;了解到HttpRuuner开源自动化测试框架&#xff0c;采用YAML/JSON格式管理用例&#xff0c;能录制和转换生成用例功能&#xff0c;充分做到用例与测试代码分离&#xff0c;相比excel维护测试场景数据更加简洁。在此&#xff0c;利用业…

算法Day23 简单吃饭(0-1背包)

简单吃饭&#xff08;0-1背包&#xff09; Description Input Output Sample 代码 import java.util.Scanner; public class Main {public static void main(String[] args) {Scanner scanner new Scanner(System.in);int n scanner.nextInt();int total scanner.nextInt(…

Centos7、Mysql8.0 load_file函数返回为空的终极解决方法--暨selinux的深入理解

零、问题背景 最近想换房&#xff0c;为了方便自己对比感兴趣的房子&#xff0c;因此决定将目标房源的基本信息放在表里&#xff0c;特别是要一目了然的看到众多房子的各种图纸和照片&#xff0c;因此决定要在Mysql8.0.34数据库中以二进制形式保存图片&#xff08;抛开合理性和…

多人聊天UDP

服务端 package 多人聊天;import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList;…

蓝桥杯日期问题

蓝桥杯其他真题点这里&#x1f448; 注意日期合法的判断 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;public class Main{static int[] days {0,31,28,31,30,31,30,31,31,30,31,30,31};static BufferedReader in new Buf…

TP5上传图片压缩尺寸

图片上传&#xff0c;最简单的就是&#xff0c; 方法一&#xff1a; 修改上传限制&#xff0c;不让上传大于多少多少的图片 改一下size即可&#xff0c;默认单位是B换算成M还需要除以两次1024 方法二&#xff1a; 对上传的图片进行缩放&#xff0c;此办法网上找了不少的代码…

了解c++11中的新增

一&#xff0c;统一的初始化列表 在引入c11后&#xff0c;我们得出计划都可以用初始化列表进行初始化。 C11 扩大了用大括号括起的列表 ( 初始化列表 ) 的使用范围&#xff0c;使其可用于所有的内置类型和用户自 定义的类型&#xff0c; 使用初始化列表时&#xff0c;可添加等…

JDK中lock锁的机制,其底层是一种无锁的架构实现的,公平锁和非公平锁

简述JDK中lock锁的机制&#xff0c;其底层是一种无锁的架构实现的&#xff0c;是否知道其是如何实现的 synchronized与lock lock是一个接口&#xff0c;而synchronized是在JVM层面实现的。synchronized释放锁有两种方式&#xff1a; 获取锁的线程执行完同步代码&#xff0c;…

androidstudio设置内存

androidstudio一直 scanning files to index&#xff0c;需要去设置内存&#xff1a; 操作如下&#xff1a;

在Mac上安装Windows应用程序的简便方法:CrossOver for Mac

对于许多Mac用户来说&#xff0c;有时候他们可能需要使用一些只有在Windows上才能找到的应用程序。以前&#xff0c;解决这个问题的方法是通过安装Windows虚拟机或使用双系统来在Mac上运行Windows应用程序。但这些方法需要额外的硬件资源和时间来配置&#xff0c;并且可能会导致…

MEME成风,为何比特币生态无法复刻以太坊生态的多样玩法?

铭文市场火了之后&#xff0c;很多人对 BTC L2 投入了过多的期许&#xff0c;认为 BTC 2 层会像以太坊 layer2 一样辉煌&#xff1f; 然而事实是&#xff0c;比特币生态的「成功」可能很长时间会停滞在「资产发行」叙事阶段&#xff0c;要复刻以太坊的生态多样玩法&#xff0c…

栈和队列OJ题

有效的括号 OJ链接 思路 要注意进行顺序匹配的时候&#xff0c;要让右括号和栈顶元素匹配&#xff0c;匹配了一个以后就要让栈顶元素出栈&#xff01;&#xff01; 在顺序匹配时&#xff0c;要用 *s ] && top ! [ 像这样的不等号&#xff0c;而不能用&#xff0c;因为…

12.4_黑马MybatisPlus笔记(下)

目录 11 12 thinking&#xff1a;关于Mybatis Plus中BaseMapper和IService&#xff1f; 13 ​编辑 thinking&#xff1a;CollUtil.isNotEmpty? 14 thinking&#xff1a;Collection、Collections、Collector、Collectors&#xff1f; thinking&#xff1a;groupBy&#…

前端打包环境配置步骤

获取node安装包并解压 获取node安装包 wget https://npmmirror.com/mirrors/node/v16.14.0/node-v16.14.0-linux-x64.tar.xz 解压 tar -xvf node-v16.14.0-linux-x64.tar.xz 创建软链接 sudo ln -s 此文件夹的绝对路径/bin/node /usr/local/bin/node&#xff0c;具体执行如下…

彻底搞懂零拷贝技术( DMA、PageCache)

DMA 直接内存访问&#xff08;Direct Memory Access&#xff09; 什么是DMA&#xff1f; 在进行数据传输的时候&#xff0c;数据搬运的工作全部交给 DMA 控制器&#xff0c;而 CPU 不再参与&#xff0c;可以去干别的事情。 传统I/O 在没有 DMA 技术前&#xff0c;全程数据…

AIGC之Image2Video(一)| Animate Anyone:从静态图像生成动态视频,可将任意图像角色动画化

近日&#xff0c;阿里发布了Animate Anyone&#xff0c;只需一张人物照片&#xff0c;结合骨骼动画&#xff0c;就能生成人体动画视频。 项目地址&#xff1a;https://humanaigc.github.io/animate-anyone/ 论文地址&#xff1a;https://arxiv.org/pdf/2311.17117.pdf Github…

YOLOv8 YoLov8l 模型输出及水果识别

&#x1f368; 本文为[&#x1f517;365天深度学习训练营学习记录博客 &#x1f366; 参考文章&#xff1a;365天深度学习训练营 &#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制] &#x1f680; 文章来源&#xff1a;[K同学的学习圈子](https://www.yuque.com/m…

Android app性能优化指南

Android应用性能优化指南 提高应用程序的性能以实现更流畅的用户体验和更高的可见度。 性能在任何应用程序的成功中发挥着重要的作用。为用户提供流畅无缝的体验应该是开发人员的重点。 应用程序大小 在用户开始使用我们的应用程序之前&#xff0c;他们需要下载应用程序并将…