java实现url的word地址转换为pdf文件操作(文件最终存储ftp里nginx映射展示,项目部署到k8s里)
上周分配的任务功能是将word转化为pdf文件,在转换的过程中还需要替换文档内容(ps不会将原有内容文档更改),查询了一些资料发现java还是蛮难实现的,资料也是不多的,尤其我们的环境还是k8s里部署,就增大了很多困难,实践了很久最终成功将word转换成pdf文件了。首先给我的word地址是url方式的地址,"http://ip/文件名称.docx"的http方式,我需要请求这个地址转换成in..
·
上周分配的任务功能是将word转化为pdf文件,在转换的过程中还需要替换文档内容(ps不会将原有内容文档更改),查询了一些资料发现java还是蛮难实现的,资料也是不多的,尤其我们的环境还是k8s里部署,就增大了很多困难,实践了很久最终成功将word转换成pdf文件了。
首先给我的word地址是url方式的地址,"http://ip/文件名称.docx"的http方式,我需要请求这个地址转换成inputStream输入流,再用word流转换成pdf,转换成pdf文件以后上传到ftp中,供nginx映射以http形式访问。
1.操作word与pdf的包
<!-- ftp -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.3</version>
</dependency>
<!-- word转换成pdf的工具包-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>xdocreport</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-support</artifactId>
<version>2.1.8</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.7</version>
</dependency>
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext-rtf</artifactId>
<version>2.1.7</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<!-- word转换成pdf的工具包-->
2.根据url路径获取输入流
/**
* 根据url路径获取输入流
*
* @param strUrl http://192.168.7.115:30020/ceshi.docx
* @return
*/
public InputStream getInputStreamByUrl(String strUrl) {
InputStream inputStream = null;
try {
URL url = new URL(strUrl);
conn = (HttpURLConnection) url.openConnection();
//以Post方式提交表单,默认get方式
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.setDoOutput(true);
// post方式不能使用缓存
conn.setUseCaches(false);
//连接指定的资源
conn.connect();
//获取网络输入流
inputStream = conn.getInputStream();
return inputStream;
} catch (Exception e) {
log.error("getInputStreamByUrl 异常,exception is {}", e);
urlClose();
inputStreamClose(inputStream);
}
return null;
}
3.用word流转换pdf文件
/**
* 用word流转换pdf文件
*
* @param modelBase 实体属性
* @param results 替换内容的数据
*/
public String wordtoPdf(GsaModelBase modelBase, List<GsaModelMethodResult> results) {
String filename = null;
if (modelBase.getFilename() != null) {
int index = modelBase.getFilename().indexOf(".");
filename = "/" + modelBase.getFilename().substring(0, index) + ".pdf";
}
// 获取文档输入流
InputStream intstream = getInputStreamByUrl(modelBase.getFileurl());
PdfOptions options = PdfOptions.create();
// 字体文件放入项目中并读取项目路径
ClassPathResource classPathResource = new ClassPathResource("fort/SIMSUN.TTC,1");
log.info("字体路径:{}", classPathResource.getPath());
// 设置字体,必要没有此代码部署到容器里中文将不显示
options.fontProvider(new IFontProvider() {
public Font getFont(String familyName, String encoding, float size, int style, Color color) {
try {
BaseFont bfChinese = BaseFont.createFont(classPathResource.getPath(), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
com.lowagie.text.Font fontChinese = new com.lowagie.text.Font(bfChinese, size, style, color);
if (familyName != null)
fontChinese.setFamily(familyName);
return fontChinese;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
// 释放资源
urlClose();
inputStreamClose(intstream);
}
}
});
try {
// 输出地址,此地址为容器根目录
OutputStream target = new FileOutputStream(filename);
// 替换文档内容
Map<String, String> params = new HashMap<String, String>();
params.put("广东", "北京");
// 将word转换成pdf
WordToPDFUtil.wordConverterToPdf(intstream, target, options, params);
log.info("target:" + target);
//将转换pdf的容器路径转换stream
File file = new File(filename);
InputStream in = new FileInputStream(file);
//pdf文件上传到ftp里,为了外部nginx访问。
boolean isSuccess = ftpUtil.uploadFileToFtp(in, filename.replace("/", ""), filePath);
if (isSuccess) {
log.info("上传成功!");
}
// 删除容器中的文件
} catch (Exception e) {
e.printStackTrace();
} finally {
// 释放资源
urlClose();
inputStreamClose(intstream);
}
return filename;
}
4.释放流和连接方式
/**
* 关闭HttpURLConnection
*/
public void urlClose() {
if (conn != null) {
conn.disconnect();
}
}
/**
* 关闭InputStream
*
* @param inputStream
*/
public void inputStreamClose(InputStream inputStream) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
5.字体文件存放位置,放在resource下面就好了
6.将word文档转换pdf的工具类
package gsa.geographic.land.util;
import com.baomidou.mybatisplus.toolkit.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xwpf.converter.pdf.PdfConverter;
import org.apache.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.poi.xwpf.usermodel.*;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author df
* @Date 2020/2/20 16:35
* @Version 1.0
*/
public class WordToPDFUtil {
/**
* 将word文档, 转换成pdf, 中间替换掉变量
*
* @param source 源为word文档, 必须为docx文档
* @param target 目标输出
* @param params 需要替换的变量
* @throws Exception
*/
public static void wordConverterToPdf(InputStream source,
OutputStream target, Map<String, String> params) throws Exception {
wordConverterToPdf(source, target, null, params);
}
/**
* 将word文档, 转换成pdf, 中间替换掉变量
*
* @param source 源为word文档, 必须为docx文档
* @param target 目标输出
* @param params 需要替换的变量
* @param options PdfOptions.create().fontEncoding( "windows-1250" ) 或者其他
* @throws Exception
*/
public static void wordConverterToPdf(InputStream source, OutputStream target,
PdfOptions options,
Map<String, String> params) throws Exception {
XWPFDocument doc = new XWPFDocument(source);
paragraphReplace(doc.getParagraphs(), params);
for (XWPFTable table : doc.getTables()) {
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
paragraphReplace(cell.getParagraphs(), params);
}
}
}
PdfConverter.getInstance().convert(doc, target, options);
}
/**
* 替换段落中内容
*/
private static void paragraphReplace(List<XWPFParagraph> paragraphs, Map<String, String> params) {
if (MapUtils.isNotEmpty(params)) {
for (XWPFParagraph p : paragraphs) {
for (XWPFRun r : p.getRuns()) {
r.setFontFamily("宋体");
String content = r.getText(r.getTextPosition());
System.out.println(content);
if (StringUtils.isNotEmpty(content) && params.containsKey(content)) {
r.setText(params.get(content), 0);
}
}
}
}
}
}
7.ftp上传代码
Logger logger = LoggerFactory.getLogger(FTPUtil.class);
private String LOCAL_CHARSET = "GBK";
// 该目录不存在
public static final String DIR_NOT_EXIST = "该目录不存在";
// 该目录下没有文件
public static final String DIR_CONTAINS_NO_FILE = "该目录下没有文件";
// ftp服务器地址
@Value("${ftp.ip}")
private String hostname;
// ftp服务器端口
@Value("${ftp.port}")
private int port;
// ftp登录账号
@Value("${ftp.username}")
private String username;
// ftp登录密码
@Value("${ftp.password}")
private String password;
// ftp保存目录
@Value("${ftp.filePath}")
private String filePath; // 文件
/**
* 初始化ftp服务器
*/
public FTPClient getFtpClient() {
FTPClient ftpClient = new FTPClient();
ftpClient.setControlEncoding("utf-8");
try {
ftpClient.setDataTimeout(1000 * 120);//设置连接超时时间
logger.info("connecting...ftp服务器:" + hostname + ":" + port);
ftpClient.connect(hostname, port); // 连接ftp服务器
ftpClient.login(username, password); // 登录ftp服务器
int replyCode = ftpClient.getReplyCode(); // 是否成功登录服务器
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand(
"OPTS UTF8", "ON"))) { // 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
LOCAL_CHARSET = "UTF-8";
}
if (!FTPReply.isPositiveCompletion(replyCode)) {
logger.error("connect failed...ftp服务器:" + hostname + ":" + port);
}
logger.info("connect successfu...ftp服务器:" + hostname + ":" + port);
} catch (MalformedURLException e) {
logger.error(e.getMessage(), e);
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
return ftpClient;
}
/**
* 文件上传根据流文件
*
* @param inputStream 文件流
* @param fileName
* @param path
* @return
*/
public boolean uploadFileToFtp(InputStream inputStream, String fileName, String path) {
boolean isSuccess = false;
FTPClient ftpClient = getFtpClient();
try {
if (ftpClient.isConnected()) {
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);//设置上传文件类型为二进制,否则将无法打开文件
logger.info("开始上传文件到FTP,文件名称{}:,上传路径:{}", fileName, path);
ftpClient.makeDirectory(path);
ftpClient.changeWorkingDirectory(path);
//设置为被动模式(如上传文件夹成功,不能上传文件,注释这行,否则报错refused:connect )
ftpClient.enterLocalPassiveMode();//设置被动模式,文件传输端口设置
ftpClient.storeFile(fileName, inputStream);
logger.info(fileName, "{}文件上传到FTP成功");
isSuccess = true;
ftpClient.logout();
} else {
logger.error("FTP连接建立失败");
}
} catch (Exception e) {
logger.error("文件上传到FTP出现异常");
logger.error(e.getMessage(), e);
}
return isSuccess;
}
以上就是全部内容,可以解决部署k8s容器中word转换pdf存储文件的地方,也可以解决k8s容器部署或linux部署word转换pdf不显示中文的问题,希望可以帮助你!
更多推荐
已为社区贡献8条内容
所有评论(0)