目录
问题
工作中遇到一个需求,需要实现 excel 文件的预览,实现的思路就是将 excel 转成 pdf 文件,上传到文件服务器上得到文件地址,预览时只需要返回 pdf 预览文件地址即可。
所以主要的问题就是如何将 excel 转为 pdf,调研了相关的技术,最简单的就是使用 aspose 类库,直接一个api调用就搞定了。但是直接这么使用会出现转换后的 pdf 文件单元格没有表格线,表格列过多会自动分页,单元格内容过多时,在 pdf 的单元格里内容显示不全情况。
前置环境
由于 aspose 产品并不是免费的,如果直接使用,转换后的 pdf 会带有水印。
网上能找到破解版的 license,对应的 jar 包是 apose-cells-8.5.2.jar,这个版本已经在 maven 中已经下载不到了,所以需要从网上找到资源下载。
apose-cells-8.5.2.jar
链接:嘿嘿嘿
提取码:eqy8
下载 apose-cells-8.5.2.jar,这里是放到了 resource/lib 下
license.xml
内容如下
<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>
pom
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-cells</artifactId>
<version>8.5.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/lib/aspose-cells-8.5.2.jar</systemPath>
</dependency>
excel
准备一个 excel 文件,列多一些,并且每个单元格内容长度都大于显示的长度
问题复现
使用 aspose 转 excel 为 pdf 非常方便,只需要调个 api 就行了
Excel2PDFUtil
public class Excel2PDFUtil {
public static boolean getLicense() {
boolean result = false;
try {
InputStream is = Excel2PDFUtil .class.getClassLoader().getResourceAsStream("\\license.xml");
License asposeLic = new License();
asposeLic.setLicense(is);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* excel 转 pdf
*
* @param excelPath excel文件路径
* @param pdfPath pdf文件路径
*/
public static Boolean excel2pdf(String excelPath, String pdfPath) {
if (!getLicense()) {
return false;
}
try {
Workbook wb = new Workbook(excelPath);
File pdfFile = new File(pdfPath);
FileOutputStream fileOS = new FileOutputStream(pdfFile);
wb.save(fileOS, SaveFormat.PDF);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
测试代码
class Excel2PDFUtilTest {
@Test
void excel2pdf() {
String excelPath = "C:\\Users\\luhc\\Desktop\\excel.xlsx";
String pdfPath = "C:\\Users\\luhc\\Desktop\\pdf.pdf";
Excel2PDFUtil.excel2pdf(excelPath, pdfPath);
}
}
生成的 PDF 如下所示
可以看到转换后的 PDF 单个表格被分成了 2 页面来显示,而且每行单元格没有边框,并且每个单元格显示的内容也不全,这样转换得到的 pdf 是没有任何用处的,毫无意义。
如何解决
单元格的边框和单元格内容显示不全的问题,是可以在 excel 中设置单元格边框和文本自动换行来解决,这样直接转换的 pdf 就没问题了,这些设置实际上也可以由代码来设置,就不用去考虑 excel 源文件的单元格格式是否符合要求了。
至于列过多导致的分页问题,则可以在转换 pdf 时设置缩放参数
PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
pdfSaveOptions.setOnePagePerSheet(true);
最终代码
public class Excel2PDFUtil {
public static boolean getLicense() {
boolean result = false;
try {
InputStream is = Excel2PDFUtil.class.getClassLoader().getResourceAsStream("\\license.xml");
License asposeLic = new License();
asposeLic.setLicense(is);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* excel 转 pdf
*
* @param excelPath excel文件路径
* @param pdfPath pdf文件路径
*/
public static Boolean excel2pdf(String excelPath, String pdfPath) {
if (!getLicense()) {
return false;
}
try {
Workbook wb = new Workbook(excelPath);
WorksheetCollection sheets = wb.getWorksheets();
int sheetCount = sheets.getCount();
for (int i = 0; i < sheetCount; i++) {
Worksheet sheet = sheets.get(i);
sheet.autoFitRows();
Cells cells = sheet.getCells();
int maxRow = cells.getMaxRow();
int maxColumn = cells.getMaxColumn();
for (int j = 0; j < maxRow; j++) {
for (int k = 0; k < maxColumn; k++) {
Cell cell = cells.get(j, k);
Style style = cell.getStyle();
BorderCollection borders = style.getBorders();
borders.getByBorderType(BorderType.TOP_BORDER).setLineStyle(CellBorderType.THIN);
borders.getByBorderType(BorderType.TOP_BORDER).setColor(Color.getBlack());
borders.getByBorderType(BorderType.BOTTOM_BORDER).setLineStyle(CellBorderType.THIN);
borders.getByBorderType(BorderType.BOTTOM_BORDER).setColor(Color.getBlack());
borders.getByBorderType(BorderType.LEFT_BORDER).setLineStyle(CellBorderType.THIN);
borders.getByBorderType(BorderType.LEFT_BORDER).setColor(Color.getBlack());
borders.getByBorderType(BorderType.RIGHT_BORDER).setLineStyle(CellBorderType.THIN);
borders.getByBorderType(BorderType.RIGHT_BORDER).setColor(Color.getBlack());
style.setHorizontalAlignment(TextAlignmentType.CENTER);
cell.setStyle(style);
}
}
}
File pdfFile = new File(pdfPath);
FileOutputStream fileOS = new FileOutputStream(pdfFile);
PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
pdfSaveOptions.setOnePagePerSheet(true);
wb.save(fileOS, pdfSaveOptions);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}