摘要:在项目过程中提出一个需要将doc在线预览并且要实现分页功能。
前端实现的缺点:1、只能预览docx文件,无法兼容doc,而且后端强制将doc转为docx的文件,前端也无法实现预览。2、前端无法进行分页展示。
一、后端实现需要引入jar包,以下是常用jar分析:
基于Openoffice | 基于libreOffice | 基于Office | 基于Pio+Itext | 基于Aspose | |
跨平台性 | 跨平台 | 跨平台 | 仅Windows | 跨平台 | 跨平台 |
是否安装软件 | 需安装Openoffice | 需安装libreOffice | 需安装MicrosoftOffice | 否 | 否 |
是否收费 | 免费 | 免费 | 软件收费 | 免费 | Jar包收费(可破解) |
优点 | 跨平台 文档转换失真小。 | 跨平台 转化相对快。 | 对于Office能很好保证少失真,特别是Word文档 跨平台 转换速度快。 | 支持跨平台。 |
不需要安装软件,失真情况较小。 |
缺点 | 需要安装额外软件 | 需要安装额外软件、效率较低 |
不跨平台需安装Office Office收费 Office版本不同效果不同(不稳定性) |
样式失真特别严重、效率极低。技术复杂 | 收费(但是可以破解)、即使付费,也不提供源码(官网) |
综合来看基于Aspose是最优方式,以下是实现方式。
二、实现
1、jar包引用
<!--文件转pdf工具类--> <dependency> <groupId>com.aspose</groupId> <artifactId>aspose-words</artifactId> <version>15.8.0</version> </dependency> <dependency> <groupId>com.aspose</groupId> <artifactId>aspose-cells</artifactId> <version>8.5.2</version> </dependency> <dependency> <groupId>com.aspose</groupId> <artifactId>aspose-slides</artifactId> <version>15.9.0</version> </dependency>
2、工具类
import com.aspose.cells.Workbook; import com.aspose.slides.Presentation; import com.aspose.words.Document; import com.aspose.words.SaveFormat; import java.io.*; /** * @Classname OnlinePreviewUtil * @Description TODO * @Date 2023/8/8 10:15 * @Created by laity2020 * @Author:Yan */ public class OnlinePreviewUtil { /** * 文件转换 * * @param source:源文件地址 如:C://test/test.doc,target:转换后文件路径 如 C://test/pdf * @return */ public static String officeToPdf(InputStream source, OutputStream target,String fileName) { String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1); if ("doc".equals(fileExt) || "docx".equals(fileExt)) { doc2pdf(source, target); } if ("xls".equals(fileExt) || "xlsx".equals(fileExt)) { excel2pdf(source, target); } if ("ppt".equals(fileExt) || "pptx".equals(fileExt)) { ppt2pdf(source, target); } if ("doc,docx,xls,xlsx,ppt,pptx".indexOf(fileExt) > 0) { return target + File.separator + (fileName.replace(fileExt, "pdf")); } return null; } /** * @description: 验证ExcelLicense */ public static boolean getExcelLicense() { boolean result = false; try { // license.xml应放在..\WebRoot\WEB-INF\classes路径下 InputStream is = OnlinePreviewUtil.class.getClassLoader().getResourceAsStream("license.xml"); com.aspose.cells.License aposeLic = new com.aspose.cells.License(); aposeLic.setLicense(is); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } /** * @description: 验证PPTtlLicense */ public static boolean getPPTLicense() { boolean result = false; try { // license.xml应放在..\WebRoot\WEB-INF\classes路径下 InputStream is = OnlinePreviewUtil.class.getClassLoader().getResourceAsStream("license.xml"); com.aspose.slides.License aposeLic = new com.aspose.slides.License(); aposeLic.setLicense(is); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } /** * @description: 验证License */ public static boolean getDocLicense() { boolean result = false; try { // license.xml应放在..\WebRoot\WEB-INF\classes路径下 InputStream is = OnlinePreviewUtil.class.getClassLoader().getResourceAsStream("license.xml"); com.aspose.words.License aposeLic = new com.aspose.words.License(); aposeLic.setLicense(is); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } /** * @description: doc转pdf * @params: source:源文件,target:转换后文件 */ public static void doc2pdf(InputStream source, OutputStream target) { // 验证License 若不验证则转化出的pdf文档会有水印产生 if (!getDocLicense()) { return; } try { Document doc = new Document(source); doc.save(target, com.aspose.words.SaveFormat.PDF); } catch (Exception e) { e.printStackTrace(); } } /** * @description: excel转pdf * @params: source:源文件地址,target:转换后文件路径,fileExt:后缀 */ public static void excel2pdf(InputStream source, OutputStream target) { // 验证License 若不验证则转化出的pdf文档会有水印产生 if (!getExcelLicense()) { return; } try { // 原始excel路径 Workbook wb = new Workbook(source); wb.save(target, com.aspose.cells.SaveFormat.PDF); } catch (Exception e) { e.printStackTrace(); } } /** * @description: ppt转pdf * @params: source:源文件地址,target:转换后文件路径,fileExt:后缀 */ public static void ppt2pdf(InputStream source, OutputStream target) { // 验证License 若不验证则转化出的pdf文档会有水印产生 if (!getPPTLicense()) { return; } try { //输入pdf路径 Presentation pres = new Presentation(source); pres.save(target, SaveFormat.PDF); target.close(); } catch (Exception e) { e.printStackTrace(); } } }
3、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>
4、调用方式,我采用的用文件流的形式,减少文件的生成。
OnlinePreviewUtil.officeToPdf(inputStream, outputStream(),realName);
注:在这个过程中小编尝试了很多方法,因为本身项目采用了poi,引入dom4j、itextpdf和fr.opensagres.poi.xwpf.converter.pdf-gae时均因jar包冲突导致文件转pdf失败,以上是能完美实现并不poi不冲突的方式,遂进行记录,最后附上jar下载。
链接:https://pan.baidu.com/s/1fC8rE4faIV8g39HiKo1P5w?pwd=do50
提取码:do50