项目场景:
需求描述:上传附件后,可实现在线预览,这里就会存在一个问题,很多附件的类型是没法在线预览的,点击就会下载。除pdf/jpg/jpeg等,于是技术方案定,将word/excel等类型的文件转成pdf,并且使用nginx代理附件路径,实现预览效果。
技术实现
提示:要考虑到,一个附件肯定会被多人点击预览,从表结构设计的角度,要多加一个preview_path(预览文件地址)字段,第一次生成pdf后,将链接持久化到数据库,之后只有该值不为空,查询直接返回即可。
aspose从maven仓库拉取不下来,需手动下载本地添加到项目中。
aspose-cells-8.5.2.jar
aspose-words-15.8.0-jdk16.jar
链接:https://pan.baidu.com/s/1YBAfBJF2mzPDaJqxjQ6jkg 密码:srco
pom.xml添加
注意:maven打包的时候,要加上这句,不然打包有问题
ok,堆代码吧
<?xml version="1.0" encoding="UTF-8"?>
<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>
枚举类,支持的附件类型,按自己需求增减
package com.szls.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* com.szls.enums
*
* @author smallNorth_Lee
* @date 2022/8/11
*/
@Getter
@AllArgsConstructor
public enum FileTypeEnum {
PDF(".pdf"),
XLSX(".xlsx"),
DOCX(".docx"),
DOC(".doc");
/**
* 文件类型
*/
private final String fileType;
}
package com.szls.utils;
import com.aspose.words.*;
import com.szls.enums.FileTypeEnum;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* word转化成pdf,实现在线预览
*
* @author smallNorth_Lee
* @date 2022/8/10
*/
@Component
@RequiredArgsConstructor
public class AsposeWordUtil {
private final AsposeExcelUtil asposeExcelUtil;
/**
* 验证License 若不验证则转化出的pdf文档会有水印产生
*/
@SneakyThrows
private static void getLicense() {
try (InputStream is = AsposeWordUtil.class.getClassLoader().getResourceAsStream("License.xml")) {
License license = new License();
license.setLicense(is);
}
}
/**
* word转pdf
*
* @param filePath 原文件地址
* @param pdfFilePath pdf 文件地址
* @param fileType 文件类型
*/
public void fileToPdf(String filePath, String pdfFilePath, String fileType) {
if (FileTypeEnum.XLSX.getFileType().equals(fileType)) {
asposeExcelUtil.excelToPdf(filePath, pdfFilePath);
return;
}
getLicense();
File file = new File(pdfFilePath);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
FileOutputStream os = null;
try {
os = new FileOutputStream(file);
Document doc = new Document(filePath);
TableCollection tables = doc.getFirstSection().getBody().getTables();
for (Table table : tables) {
RowCollection rows = table.getRows();
table.setAllowAutoFit(false);
for (Row row : rows) {
CellCollection cells = row.getCells();
for (Cell cell : cells) {
CellFormat cellFormat = cell.getCellFormat();
cellFormat.setFitText(false);
cellFormat.setWrapText(true);
}
}
}
if (FileTypeEnum.DOC.getFileType().equals(fileType) || FileTypeEnum.DOCX.getFileType().equals(fileType)) {
doc.save(os, SaveFormat.PDF);
} else {
throw new RuntimeException("暂不支持该文件类型在线预览!");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
package com.szls.utils;
import com.aspose.cells.*;
import lombok.SneakyThrows;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* excel转化成pdf,实现在线预览
*
* @author smallNorth_Lee
* @date 2022/8/10
*/
@Component
public class AsposeExcelUtil {
/**
* 验证License 若不验证则转化出的pdf文档会有水印产生
*/
@SneakyThrows
private static void getLicense() {
try (InputStream is = AsposeExcelUtil.class.getClassLoader().getResourceAsStream("License.xml")) {
License license = new License();
license.setLicense(is);
}
}
/**
* excel转pdf
*
* @param filePath 原文件地址
* @param pdfFilePath pdf 文件地址
*/
public void excelToPdf(String filePath, String pdfFilePath) {
getLicense();
File file = new File(pdfFilePath);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
FileOutputStream os = null;
try {
Workbook workbook = new Workbook(filePath);
WorksheetCollection worksheet = workbook.getWorksheets();
Worksheet sheet = worksheet.get(0);
sheet.getPageSetup().setPrintGridlines(false);
os = new FileOutputStream(file);
workbook.save(os, SaveFormat.PDF);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
注意⚠️:这里的每一个类,不要引错jar包,每个方法都是独立的类!!!!
存在问题及解决方案:
代码写完,开开心心部署到服务器,小手那么一点,文件转换没问题!!!,举国欢庆,关机跑路!!!!
突然前端同学:你这导出怎么乱码!!!!辣鸡
于是你开始沉默,堕落,自我拉扯…
hold on bro,因为linux 缺少字体,windows直接去找c:\windows\fonts
把这些文件上传到服务器上,新建一个文件夹
mkdir /usr/share/fonts/win
sudo mkfontscale
sudo mkfontdir
sudo fc-cache -fv -v
sudo chmod 755 /usr/share/fonts/win
fc-list :lang=zh
服务重启,重新执行方法,OK~~~~~~~