如果想要免费的,可以用 openoffice,实现原理就是:
通过第三方工具openoffice,将word、excel、ppt、txt等文件转换为pdf文件流;当然如果装了Adobe Reader XI,那把pdf直接拖到浏览器页面就可以直接打开预览,前提就是浏览器支持pdf文件浏览。
文章目录
- 一、安装openoffice
- 1. windows环境
- 2. linux环境
- 二、springboot项目
- 2.1. 导入依赖
- 2.2. controller
- 2.2. 接口
- 2.3. 实现类
- 2.4. 格式转换
- 2.5. 配置类
- 2.6. 扩展配置
- 2.7. 全局配置
- 2.8. 项目源码
- 2.9. 项目拉取
- 2.10.效果图
- 三、源码心得分享
- 3.1. 适配兼容
- 3.2. 兼容不足
- 3.3. 解决方案
一、安装openoffice
1. windows环境
openoffice 安装windows 环境
2. linux环境
openoffice 安装 linux环境
二、springboot项目
2.1. 导入依赖
<dependency><groupId>com.artofsolving</groupId><artifactId>jodconverter</artifactId><version>2.2.1</version></dependency>
2.2. controller
package com.gblfy.controller;import com.gblfy.service.IPreviewService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletResponse;/*** @author gblfy* @date 2021-10-28*/
@Api(tags = "在线预览入口")
@RestController
@RequestMapping("/file/onlinePreview")
public class PreviewController {@Autowiredprivate IPreviewService previewService;//在线预览处理类/*** 在线预览主入口** @param fileUrl* @param response* @throws Exception*/@ApiOperation("在线预览主方法")@PostMapping("/api")public void onlinePreview(@RequestParam("fileUrl") String fileUrl, HttpServletResponse response) throws Exception {previewService.onlinePreview(fileUrl, response);}
}
2.2. 接口
package com.gblfy.service;import javax.servlet.http.HttpServletResponse;/*** 文件在线预览接口** @author gblfy* @date 2021-10-28*/
public interface IPreviewService {void onlinePreview(String url, HttpServletResponse response) throws Exception;
}
2.3. 实现类
package com.gblfy.service.impl;import com.gblfy.consts.FileTypeConst;
import com.gblfy.service.IPreviewService;
import com.gblfy.utils.FileConvertUtil;
import org.springframework.stereotype.Service;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;/*** 在线预览处理类** @author gblfy* @date 2021-10-28*/
@Service
public class PreviewServiceImpl implements IPreviewService {/*** 文件在线预览** @param fileUrl 预览的文件路径* @param response 以pdf文件流的形式返回浏览器完成预览操作* @throws Exception*/@Overridepublic void onlinePreview(String fileUrl, HttpServletResponse response) throws IOException {//对url中文件名称进行统一编码,解决400问题String uRLEncoder = FileConvertUtil.encodeUrlFileName(fileUrl);//获取文件类型 注意不要携带.String suffix = FileConvertUtil.suffixFromFileName(uRLEncoder);if (!FileTypeConst.TXT.equals(suffix) && !FileTypeConst.DOC.equals(suffix)&& !FileTypeConst.DOCX.equals(suffix) && !FileTypeConst.XLS.equals(suffix)&& !FileTypeConst.XLSX.equals(suffix) && !FileTypeConst.PPT.equals(suffix)&& !FileTypeConst.PPTX.equals(suffix)) {throw new RuntimeException("该文件格式不支持预览");}//文件转换处理InputStream in = FileConvertUtil.convertNetFile(uRLEncoder, suffix);OutputStream outputStream = response.getOutputStream();//创建存放文件内容的数组byte[] buff = new byte[1024];//所读取的内容使用n来接收int n;//当没有读取完时,继续读取,循环while ((n = in.read(buff)) != -1) {//将字节数组的数据全部写入到输出流中outputStream.write(buff, 0, n);}//强制将缓存区的数据进行输出outputStream.flush();//关流outputStream.close();in.close();}
}
2.4. 格式转换
文件格式转换工具类
package com.gblfy.utils;import com.artofsolving.jodconverter.DefaultDocumentFormatRegistry;
import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.DocumentFormat;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.StreamOpenOfficeDocumentConverter;
import org.springframework.stereotype.Component;import java.io.*;
import java.net.*;/*** 文件格式转换工具类** @author gblfy* @date 2021-10-28*/
@Component
public class FileConvertUtil {/*** 默认转换后文件后缀*/private static final String DEFAULT_SUFFIX = "pdf";/*** openoffice_port*/private static final Integer OPENOFFICE_PORT = 8100;/*** 方法描述 office文档转换为PDF(处理本地文件)** @param sourcePath 源文件路径* @param suffix 源文件后缀* @return InputStream 转换后文件输入流* @author tarzan*/public static InputStream convertLocaleFile(String sourcePath, String suffix) throws Exception {File inputFile = new File(sourcePath);InputStream inputStream = new FileInputStream(inputFile);return covertCommonByStream(inputStream, suffix);}/*** 方法描述 office文档转换为PDF(处理网络文件)** @param netFileUrl 网络文件路径* @param suffix 文件后缀* @return InputStream 转换后文件输入流* @author tarzan*/public static InputStream convertNetFile(String netFileUrl, String suffix) throws IOException {// 创建URLURL url = new URL(netFileUrl);// 试图连接并取得返回状态码URLConnection urlconn = url.openConnection();urlconn.connect();HttpURLConnection httpconn = (HttpURLConnection) urlconn;int httpResult = httpconn.getResponseCode();if (httpResult == HttpURLConnection.HTTP_OK) {InputStream inputStream = urlconn.getInputStream();//文件转换return covertCommonByStream(inputStream, suffix);}return null;}/*** 方法描述 将文件以流的形式转换** @param inputStream 源文件输入流* @param suffix 源文件后缀* @return InputStream 转换后文件输入流* @author tarzan*/public static InputStream covertCommonByStream(InputStream inputStream, String suffix) throws ConnectException {ByteArrayOutputStream out = new ByteArrayOutputStream();OpenOfficeConnection connection = new SocketOpenOfficeConnection(OPENOFFICE_PORT);connection.connect();DocumentConverter converter = new StreamOpenOfficeDocumentConverter(connection);DefaultDocumentFormatRegistry formatReg = new DefaultDocumentFormatRegistry();DocumentFormat targetFormat = formatReg.getFormatByFileExtension(DEFAULT_SUFFIX);DocumentFormat sourceFormat = formatReg.getFormatByFileExtension(suffix);converter.convert(inputStream, sourceFormat, out, targetFormat);connection.disconnect();return outputStreamConvertInputStream(out);}/*** 方法描述 outputStream转inputStream** @author tarzan*/public static ByteArrayInputStream outputStreamConvertInputStream(final OutputStream out) {ByteArrayOutputStream baos = (ByteArrayOutputStream) out;return new ByteArrayInputStream(baos.toByteArray());}/*** 通过文件名获取文件后缀** @param fileName 文件名称* @return 文件后缀*/public static String suffixFromFileName(String fileName) {return fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();}/*** 对url中的文件名进行UTF-8编码** @param url url* @return 文件名编码后的url*/public static String encodeUrlFileName(String url) {String noQueryUrl = url.substring(0, url.contains("?") ? url.indexOf("?") : url.length());int fileNameStartIndex = noQueryUrl.lastIndexOf('/') + 1;int fileNameEndIndex = noQueryUrl.lastIndexOf('.');String encodedFileName;try {encodedFileName = URLEncoder.encode(noQueryUrl.substring(fileNameStartIndex, fileNameEndIndex), "UTF-8");} catch (UnsupportedEncodingException e) {return null;}return url.substring(0, fileNameStartIndex) + encodedFileName + url.substring(fileNameEndIndex);}// public static void main(String[] args) {// String url ="http://127.0.0.1:8080/flies/新建MicrosoftExcel工作表.xlsx";// String ii = encodeUrlFileName(url);// System.out.println(ii);// }
}
2.5. 配置类
package com.gblfy.config;import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** web 配置类** @author gblfy* @Date 2019/11/12日 下午5:03:32*/
@Configuration
public class WebConfig implements WebMvcConfigurer {/*** 在配置文件中配置的文件保存路径*/@Value("${files.location}")private String files;/*** 静态资源映射*/@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {//本应用\static\editor\fontsregistry.addResourceHandler("/flies/**").addResourceLocations("file:" + files);}
}
2.6. 扩展配置
说明:添加扩展配置原因
解决jodconverter 2.2.1 版本不支持docx、xlsx、pptx 转换成PDF格式异常
package com.artofsolving.jodconverter;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;/*** @description: 重写 BasicDocumentFormatRegistry 文档格式* * @Author: gblfy* @Data: 2021-10-27**/
public class BasicDocumentFormatRegistry implements DocumentFormatRegistry {private List/* <DocumentFormat> */ documentFormats = new ArrayList();public void addDocumentFormat(DocumentFormat documentFormat) {documentFormats.add(documentFormat);}protected List/* <DocumentFormat> */ getDocumentFormats() {return documentFormats;}/*** @param extension the file extension* @return the DocumentFormat for this extension, or null if the extension* is not mapped*/@Overridepublic DocumentFormat getFormatByFileExtension(String extension) {if (extension == null) {return null;}//将文件名后缀统一转化if (extension.indexOf("doc") >= 0) {extension = "doc";}if (extension.indexOf("ppt") >= 0) {extension = "ppt";}if (extension.indexOf("xls") >= 0) {extension = "xls";}String lowerExtension = extension.toLowerCase();for (Iterator it = documentFormats.iterator(); it.hasNext(); ) {DocumentFormat format = (DocumentFormat) it.next();if (format.getFileExtension().equals(lowerExtension)) {return format;}}return null;}@Overridepublic DocumentFormat getFormatByMimeType(String mimeType) {for (Iterator it = documentFormats.iterator(); it.hasNext(); ) {DocumentFormat format = (DocumentFormat) it.next();if (format.getMimeType().equals(mimeType)) {return format;}}return null;}
}
2.7. 全局配置
- windows环境
# linux
#files:
# location: /app/files/
# mapping: /flies/# windows
files:location: D:/files/mapping: /flies/#server:
# port: 80
- linux环境
```bash
# linux
files:location: /app/files/mapping: /flies/# windows
#files:
# location: D:/files/
# mapping: /flies/#server:
# port: 80
安装字体
生成PDF乱码问题解决方案
2.8. 项目源码
https://gitee.com/gb_90/online-preview
2.9. 项目拉取
git clone git@gitee.com:gb_90/online-preview.git
2.10.效果图
三、源码心得分享
3.1. 适配兼容
日常office 格式文件转换可以满足,支持文件格式很多,
例如:doc、docx、xls、xlsx、ppt、pptx、txt 等,这里不一一列举
3.2. 兼容不足
-
效果图:
虽然可以满足日常office文件转换场景,但是,实现效果和原版文件有差距,如果要求不要能接受就可以。 -
excel 转换有限制
默认只支持a4纸大小,宽度超过,会在下一页打印,这一点不是太好。 -
导致的原因
转换内置了转换后的纸张大小
3.3. 解决方案
修改源码预览之前,对将要预览的尺寸大小,先办法获取到,然后再动态设置就好
格式 | 测试链接 |
---|---|
ppt | http://127.0.0.1:80/file/onlinePreview/api?fileUrl=http://127.0.0.1:80/flies/多彩工作总结计划PPT模板2.pptx |
excel | http://127.0.0.1:80/file/onlinePreview/apifileUrl=http://127.0.0.1:80/flies/中文测试.xlsx |
word | http://127.0.0.1:80/file/onlinePreview/apifileUrl=http://127.0.0.1:80/flies/前端3天速成手册.docx |