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

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

二、生成静态HTML文件
分析:在PC端上传附件的时候,启用异步线程,借助aspose组件,将附件转成成静态HTML文件,并放在单独的一个Tomcat下面,手机端预览附件的时候,直接访问这个Tomcat中的静态HTML,这样大大提升了预览速度,还不会占用手机内存,上传及预览的逻辑如下
性能优化之通过Aspose组件将Word/Excel/PPT/PDF转成HTML文件,解决大附件预览性能问题_第1张图片
转静态资源时,需要aspose组件的支持,因此需要在pom.xml中引入aspoxe相关组件


	aspose
	aspose.pdf
	17.2.0


	aspose
	aspose-cells
	17.3.0


	aspose
	aspose-slides
	17.2-jdk16


	aspose
	aspose-words
	17.3.0-jdk16

转静态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> fileList;
	private HttpServletRequest req;
	private String tranFileType;
	private String fontPath;
	
	public TransferToHtmlThread(String sourceFileRoot, String htmlPathRoot, List> 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> files = null;
		InputStream is = null;
		String fileName = null;
		String fileType = null;
		try {
			files = new ArrayList>();
			for(Map 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 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 map = new HashMap();
				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> 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提供的服务即可


你可能感兴趣的:(性能)