SpringBoot Word 2003 转 PDF 笔记
一、word模板
二、word模板生成word
/**
* 某 service
*/
@Override
public SysAttachment doExportUserAccountDetail(Long userId) {
SysAttachment attachment = new SysAttachment();
try {
// 获取用户档案
// SysUserAccount account = sysUserAccountMapper.getById(userId);
SysUserArchive archive = sysUserArchiveMapper.getByUserId(userId);
// 三级培训信息
UserTrainStatusVo userThreeTrainStatusVo = new UserTrainStatusVo();
userThreeTrainStatusVo.setTrainThreeFlag(true);
userThreeTrainStatusVo.setUserId(userId);
List<UserTrainStatusVo> userThreeTrainStatusVoList = facEmployeeOnlineTrainService.listUserTrainRecordByEntity(userThreeTrainStatusVo);
// 员工证书信息
TkJobCertificate tkJobCertificate = new TkJobCertificate();
tkJobCertificate.setBelongPersonId(userId);
List<TkJobCertificate> tkJobCertificateList = tkJobCertificateService.queryForList(tkJobCertificate);
// 培训记录
UserTrainStatusVo userTrainStatusVo = new UserTrainStatusVo();
userTrainStatusVo.setUserId(userId);
List<UserTrainStatusVo> userTrainStatusVoList = facEmployeeOnlineTrainService.listUserTrainRecordByEntity(userTrainStatusVo);
// 考试记录
UserExamRecordVo userExamRecordVo = new UserExamRecordVo();
userExamRecordVo.setUserId(userId);
List<UserExamRecordVo> userExamRecordVoList = facExamPlanService.listUserExamRecordByEntity(userExamRecordVo);
Map dataMap = new HashMap();
dataMap.put("entity", archive);
dataMap.put("userThreeTrainStatusVoList", userThreeTrainStatusVoList);
dataMap.put("tkJobCertificateList", tkJobCertificateList);
dataMap.put("userTrainStatusVoList", userTrainStatusVoList);
dataMap.put("userExamRecordVoList", userExamRecordVoList);
String rootDir = DicUtil.getPropertyValue(SysPropertiesEnum.FILE_UPLOAD_ROOT);
String outFileDir = "export" + File.separator + DateUtil.formatDate(new Date(), "yyyy-MM-dd");
String genOutRootDir = rootDir + File.separator + outFileDir;
File parentDirFile = new File(genOutRootDir);
if (!parentDirFile.exists()) {
parentDirFile.mkdirs();
}
String templatePath = "export/员工个人档案.ftl";
Template template = cfg.getTemplate(templatePath, "UTF-8");
Calendar calendar = Calendar.getInstance();
String fileName = calendar.getTimeInMillis() + ".docx";
String reportFileName = genOutRootDir + File.separator + fileName;
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(reportFileName), "utf-8"));
try {
template.process(dataMap, out);
out.flush();
} catch (TemplateException e) {
log.error("导出个人档案失败", e);
throw new BizException(ERROR);
} finally {
try {
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
String path = outFileDir + File.separator + fileName;
attachment.setPath(path.replaceAll("\\\\", "/"));
attachment.setFileType("docx");
attachment.setModuleName("EXAM");
String fileOldName = "个人档案";
attachment.setOldName(fileOldName);
sysAttachmentMapper.save(attachment);
log.debug("===> 导出文件信息:{}", attachment);
} catch (Exception e) {
log.error("导出失败", e);
throw new BizException(ERROR);
}
return attachment;
}
三、word(2003)生成PDF
3.1、依赖
<!-- 2003 word 转 pdf -->
<!-- https://repo.e-iceblue.cn/repository/maven-public/ -->
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.doc.free</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.doc</artifactId>
<version>3.5.5</version>
</dependency>
<!-- spire.doc 为付费版本,但有水印 -->
<!-- spire.doc.free 为免费版本,但有限制,最多转换页数待验证 -->
<!-- spire.doc 和 spire.doc.free 版本选择其一使用即可 -->
<!-- pom.xml添加下面内容无效,不懂 -->
<repositories>
<repository>
<id>com.e-iceblue</id>
<url>https://repo.e-iceblue.cn/repository/maven-public/</url>
</repository>
</repositories>
<mirror>
<id>com.e-iceblue</id>
<name>com.e-iceblue</name>
<url>https://repo.e-iceblue.cn/repository/maven-public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
<mirror>
<id>maven.net.cn</id>
<name>oneof the central mirrors in china</name>
<url>http://maven.net.cn/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
<mirror>
<id>nexus</id>
<name>internal nexus repository</name>
<url>http://repo.maven.apache.org/maven2</url>
<mirrorOf>central</mirrorOf>
</mirror>
关注第一个仓库地址
此依赖下载较慢
由于依赖下载比较慢,故保存到私服,
命令:
mvn deploy:deploy-file -Dmaven.test.skip=true -DgroupId=e-iceblue -DartifactId=spire.doc.free -Dversion=5.2.0 -Dpackaging=jar -Dfile=C:\Users\xx\Desktop\5.2.0\spire.doc.free-5.2.0.jar -Durl=http://用户名:密码@ip:port/repository/3rd-part/ -DrepositoryId=xxxx
注意:jar包从本地仓库复制到其他位置,否则报错,不知为什么
注意:jar包上传的目录类型为 hosted, 例如3rd_part的类型就为 hosted
package com.hopes.sd_sfes.province.util;
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import org.apache.commons.lang3.time.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
public class WordToPdfUtils {
private static final Logger log = LoggerFactory.getLogger(WordToPdfUtils.class);
private static final Long DURATION_TIME = 60 * 1000L;
private static final ThreadLocal<StopWatch> threadLocal = new ThreadLocal<>();
/**
* word 转 pdf
* @param wordFile word文件
* @return File pdf文件
*/
public static File wordToPdf(File wordFile, boolean wait) {
File file = null;
try {
final StopWatch stopWatch = new StopWatch();
stopWatch.start();
threadLocal.set(stopWatch);
final String wordPath = wordFile.getAbsolutePath();
final String docFilePathAndName = wordPath.substring(0, wordPath.lastIndexOf("."));
final String pdfPath = docFilePathAndName + ".pdf";
final Document document = new Document();
document.loadFromFile(wordPath, FileFormat.Doc);
document.saveToFile(pdfPath, FileFormat.PDF);
file = new File(pdfPath);
}catch (Exception e) {
log.error("word to pdf error !", e);
}finally {
if (wait) {
synchronized (threadLocal) {
log.debug("thread:{}", Thread.currentThread().getName());
final long time = threadLocal.get().getTime();
if (time < DURATION_TIME) {
try { threadLocal.wait(DURATION_TIME - time); }catch (InterruptedException e) { e.printStackTrace(); }
}
log.debug("thread:{} end !", Thread.currentThread().getName());
threadLocal.get().stop();
}
}
}
return file;
}
}
// 应用代码
@Override
public void run() {
String url = getSendUrl();
String apiName = getApiName();
final String token = dataToProvinceConfig.getToken();
if (StringUtil.isEmpty(url) || CollectionUtil.isEmpty(workTicketFileList) || StringUtil.isEmpty(token)) {
log.error("省平台接口调用参数错误! 接口:{}, 接口名称:{}, 数据:{}, token:{}", url, apiName, workTicketFileList, token);
return;
}
workTicketFileList.forEach(item -> {
final File pdfFile = WordToPdfUtils.wordToPdf(item.getFile(), true);
if (null == pdfFile) {
return;
}
Response response = null;
try {
response = HttpUtil.postHeadersFile(url, pdfFile, item.getWid().toString(), token);
}catch (Exception e) {
log.error("省平台接口调用异常! 接口:{}, 接口名称:{}, 数据:{}, token:{}", url, apiName, item, token);
log.error("省平台接口调用异常信息:", e);
} finally {
provinceResponseHandler.recordAndLog(dataToProvinceType, item.toString(), response, apiName);
}
});
}
// 测试代码
import org.apache.commons.lang3.time.StopWatch;
import org.junit.Test;
import java.io.File;
import java.util.concurrent.TimeUnit;
public class WordToPdfUtilsTest {
@Test
public void wordToPdf() {
new Thread(() -> {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
String wordPath = "C:\\Users\\xx\\Downloads\\盲板抽堵安全作业票.docx";
final File file = new File(wordPath);
final File pdf = WordToPdfUtils.wordToPdf(file, true);
stopWatch.stop();
System.out.println(Thread.currentThread().getName() + stopWatch.getTime());
}, "t1").start();
new Thread(() -> {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
String wordPath = "C:\\Users\\xx\\Downloads\\盲板抽堵安全作业票.docx";
final File file = new File(wordPath);
final File pdf = WordToPdfUtils.wordToPdf(file, true);
stopWatch.stop();
System.out.println(Thread.currentThread().getName() + stopWatch.getTime());
}, "t2").start();
try { TimeUnit.SECONDS.sleep(70); }catch (InterruptedException e) { e.printStackTrace(); }
}
}
四、Linux安装字体库&中文字体
https://www.cnblogs.com/dfsxh/p/11416474.html
1、windows验证无问题, 但在 Linux 环境中导出,中文乱码
2、中文