性能优化之通过Aspose组件将Word/Excel/PPT/PDF转成HTML文件,解决大附件预览性能问题

在最近的一个项目中,遇到一个非常棘手的性能问题,场景是这样的:有PC端和手机端两个应用,用户在PC端上传的附件,如word,Excel,pdf等,当用户出差或不在电脑边上时,上传的附件在手机端能够打开预览。然后问题就来了,当在PC端上传的附件比较大,在手机端想要预览就比较慢,有时候甚至打不开,怎么解决这个性能问题呢?
一、多线程分段下载
分析:在预览的时候,将原文件切分成多分,使用多线程分段下载,这种方案可以快速的下载一个大文件到本地,然后直接打开预览,但是用户不同意将附件下载到手机上,因为手机内存有限,几个大附件就把内存占满了。

二、生成静态HTML文件
分析:在PC端上传附件的时候,启用异步线程,借助aspose组件,将附件转成成静态HTML文件,并放在单独的一个Tomcat下面,手机端预览附件的时候,直接访问这个Tomcat中的静态HTML,这样大大提升了预览速度,还不会占用手机内存,上传及预览的逻辑如下
在这里插入图片描述
转静态资源时,需要aspose组件的支持,因此需要在pom.xml中引入aspoxe相关组件

<dependency>
	<groupId>aspose</groupId>
	<artifactId>aspose.pdf</artifactId>
	<version>17.2.0</version>
</dependency>
<dependency>
	<groupId>aspose</groupId>
	<artifactId>aspose-cells</artifactId>
	<version>17.3.0</version>
</dependency>
<dependency>
	<groupId>aspose</groupId>
	<artifactId>aspose-slides</artifactId>
	<version>17.2-jdk16</version>
</dependency>
<dependency>
	<groupId>aspose</groupId>
	<artifactId>aspose-words</artifactId>
	<version>17.3.0-jdk16</version>
</dependency>

转静态HTML文件核心逻辑如下

package com.mairuan.common.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aspose.cells.Workbook;
import com.aspose.slides.Presentation;
import com.aspose.words.Document;
import com.aspose.words.SaveFormat;
import com.hrsj.mcc.base.system.service.IFileOperateService;

public class TransferToHtmlThread extends Thread{

	private static final Logger logger = LoggerFactory.getLogger(TransferToHtmlThread.class);
	
	private String sourceFileRoot;
	private String htmlPathRoot;
	private List<Map<String, Object>> fileList;
	private HttpServletRequest req;
	private String tranFileType;
	private String fontPath;
	
	public TransferToHtmlThread(String sourceFileRoot, String htmlPathRoot, List<Map<String, Object>> fileList, 
			HttpServletRequest req, String tranFileType,String fontPath) {
		this.sourceFileRoot = sourceFileRoot;
		this.htmlPathRoot = htmlPathRoot + File.separator + "filedownload" + File.separator;
		this.fileList = fileList;
		this.req = req;
		this.tranFileType = tranFileType;
		this.fontPath = fontPath;
	}
	@Override
	public void run() {
		String sourceFilePath = "";
		String htmlPathPath = "";
		String filePath = "";
		File file = null;
		List<Map<String,String>> files = null;
		InputStream is = null;
		String fileName = null;
		String fileType = null;
		try {
			files = new ArrayList<Map<String,String>>();
			for(Map<String, Object> fileInfo: fileList) {
				filePath = String.valueOf(fileInfo.get("file_path")); // 存储在DB的文件路径
				fileName = String.valueOf(fileInfo.get("saved_name")); // 文件名称
				fileType = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); // 获取文件后缀
				List<String> tranTypeList = Arrays.asList(this.tranFileType.split(","));
				if (!tranTypeList.contains(fileType)) { // 不属于xlsx,xls,docx,doc,pptx,ppt,pdf类型文件不转HTML
					continue;
				}
				sourceFilePath = sourceFileRoot + File.separator  + filePath; // 原文件路径
				htmlPathPath = htmlPathRoot + filePath + ".html"; // 生成的HTML文件路径
				is = getClass().getResourceAsStream("/Aspose.Total.Java.lic"); // License认证文件,如果没有此认证,最多只能转3页
				//readContent(is);
				if (StringUtils.startsWith(fileType, "doc")) {
					com.aspose.words.License wordLicense = new com.aspose.words.License();
		            wordLicense.setLicense(is);
					Document doc = new Document(sourceFilePath);
					doc.save(htmlPathPath, SaveFormat.HTML);
				}else if (StringUtils.startsWith(fileType, "xls")) {
					com.aspose.cells.License excelLicense = new com.aspose.cells.License();
		            excelLicense.setLicense(is);
		            Workbook book = new Workbook(sourceFilePath);
		            book.save(htmlPathPath, com.aspose.cells.SaveFormat.HTML);
				}else if (StringUtils.startsWith(fileType, "ppt")) {
					com.aspose.slides.License pptLicense = new com.aspose.slides.License();
		            pptLicense.setLicense(is);
		            Presentation doc = new Presentation(sourceFilePath);
		            doc.save(htmlPathPath, com.aspose.slides.SaveFormat.Html);
				}else if (StringUtils.startsWith(fileType, "pdf")) {
					com.aspose.pdf.License pdfLicense = new com.aspose.pdf.License();
		            pdfLicense.setLicense(is);
		            com.aspose.pdf.Document.addLocalFontPath(fontPath);
		            com.aspose.pdf.Document pdfDoc = new com.aspose.pdf.Document(sourceFilePath);
		            pdfDoc.save(htmlPathPath, com.aspose.pdf.SaveFormat.Html);
				}
				htmlPathPath = htmlPathPath.replace(htmlPathRoot, ""); // 去掉配置文件指定路径
				Map<String,String> map = new HashMap<String, String>();
				map.put("id", String.valueOf(fileInfo.get("id")));
				map.put("tranPath", htmlPathPath);
				files.add(map);
			}
			if (CollectionUtils.isNotEmpty(files)) {
				IFileOperateService fileOperateService = (IFileOperateService) SpringUtils.getBean("fileOperateService");
				fileOperateService.updateTransFilePath(files);//保存转换后的静态资源文件路径到DB
			}
		}catch (Exception e) {
			logger.error("Transfer File to Html fail,The message is:", e);
		}finally {
			try {
				if (is != null) {
					is.close();
				}
			} catch (IOException e) {
			}
		}
	}
}

启异步线程将附件转成HTMl,核心逻辑如下

String tranFileType ="txt,xlsx,xls,docx,doc,pptx,ppt,zip,rar,img,jpg,pdf";
String filePath =/usr/mairuan/upload/";//PC端上传附件的存放路径
String tranFilePath ="/usr/mairuan/filepath/tran";//转换后静态资源文件的存放路径
List<Map<String,Object>> fileList = fileOperateService.uploadFile(multiFile, filePath);
String fontPath = req.getSession().getServletContext().getRealPath("/fonts/");//PDF转出来在服务端预览时可能会出现乱码,需要一些字体支持

new Thread(new TransferToHtmlThread(filePath,tranFilePath,fileList,req,tranFileType,fontPath)).start();

部署一个空的Tomcat,在Tomcat的server.xml中配置静态资源文件存放根路径,手机端预览附件时,直接请求这个Tomcat提供的服务即可

<Context docBase="/usr/mairuan/filepath/tran" path="/mairuan.mobile" reloadable="false"/>
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值