ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

轻量级SpringBoot Office文档在线预览框架

2022-08-31 19:04:47  阅读:247  来源: 互联网

标签:fileNo Office office cache String file response 轻量级 SpringBoot


框架简介

介绍:基于开源项目KkFileView源码提取出,封装成仅用于 Office文档预览(格式转换) 功能的一个通用组件; 原理是把Word转成PDF,PPT转成PDF,Excel转成HTML;
利用浏览器可以直接打开PDF和HTML的特点实现在线预览;

环境安装:目前支持OpenOffice或LibreOffice实现文档格式转换,请自行安装(推荐使用LibreOffice,转出的格式相对较好)

安装 LibreOffice教程: https://www.cnblogs.com/lwjQAQ/p/16505854.html

LibreOffice下载: https://zh-cn.libreoffice.org/

OpenOffice下载: http://www.openoffice.org/

项目运行环境: jdk1.8 SpringBoot2.0

Demo地址:https://github.com/TomHusky/kkfilemini-spring-boot-starter-demo

GitHub:https://github.com/TomHusky/kkfilemini-spring-boot-starter
Gitee:https://gitee.com/luowenjie98/kkfilemini-spring-boot-starter

在线试用地址:https://tools.go996.cn/docView/

maven依赖坐标

目前暂未上传maven中央仓库,需要自行下载源码install之后使用

<dependency>
    <groupId>io.github.tomhusky</groupId>
    <artifactId>office-preview-spring-boot-starter</artifactId>
    <version>1.0.0</version>
</dependency>

配置说明

配置名称 解释 默认值
office.plugin.home office组件的安装路径 默认为LibreOffice / OpenOffice的安装位置
office.plugin.task.timeout 文件转换的超时时间,超过这个时间则自动转换失败 5m
office.plugin.server.ports office组件占用的端口 2001,2002
office.cache.enabled 开启缓存 (true/false) true
office.cache.type 缓存类型 default(RocksDB),redis(Redisson),jdk(Map) default
office.cache.file.dir 文档转换的缓存路径,可以填绝对路径,相对路径是项目根路径 相对路径office-file文件夹
office.cache.clean.cron 清理缓存的定时任务表达式,仅在开启缓存时生效 0 0 1 * * *

yml

office:
  plugin:
    home: C:\\Program Files\\LibreOffice
    task:
      timeout: 1M
    server:
      ports: 2001,2002
  cache:
    enabled: true
    type: default
    file:
      dir: D:\project\demo
    clean:
      cron: 0 0 1 * * *

properties

office.plugin.home=C:\\Program Files\\LibreOffice
office.plugin.task.timeout=1M
office.plugin.server.ports=2001,2002
office.cache.enabled=true
office.cache.type=default
office.cache.file.dir=officeFile
office.cache.clean.cron=0 0 1 * * *

快速使用

直接注入

@Resource
private KKFileViewComponent kkFileViewComponent;

OfficeFileViewComponent中提供的方法

方法名称 解释
File convertViewFile(File file) 直接转换成可以预览的文件 word,ppt转成pdf excel转成html
String addFileToCache(File file) 添加文件到缓存,添加的时候直接转换,返回可以预览的文件编号
void addFileToCache(File file, String fileNo) 添加文件到缓存,指定文件编号(保证唯一)
boolean cacheExistFile(String fileNo) 判断文件编号是否存在缓存的文件
void viewCacheFile(HttpServletResponse response, String fileNo) 根据文件编号预览文件,直接使用response输出流;并且response的header加入file-type字段用于判断文件类型(pdf/html)

代码示例


@Service
public class FileServiceImpl implements FileService {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private KKFileViewComponent fileViewComponent;

    @Autowired
    private ObjectMapper objectMapper;

    private final Map<String, FileCacheVo> tempFilePathCache = new ConcurrentHashMap<>();

    private static final Set<String> ALLOW_FILE_TYPE = CollUtil.set(false, ".doc", ".docx", ".pdf", ".xlsx", ".xls", ".pptx", ".ppt");

    private static final List<FileInfoRespVo> FILE_SET = new CopyOnWriteArrayList<>();

    @Override
    public FileInfoRespVo uploadFile(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        assert originalFilename != null;

        String fileType = originalFilename.substring(originalFilename.lastIndexOf('.'));
        if (!ALLOW_FILE_TYPE.contains(fileType)) {
            throw new RuntimeException("不支持的文件类型!");
        }
        try {
            String fileNo = IdUtil.getSnowflakeNextIdStr();
            File tempFile = File.createTempFile(fileNo, fileType);
            FileUtil.writeFromStream(file.getInputStream(), tempFile, true);

            FileInfoRespVo fileInfoRespVo = new FileInfoRespVo();
            fileInfoRespVo.setFileNo(fileNo);
            fileInfoRespVo.setFileName(originalFilename);
            fileInfoRespVo.setFileSuffix(fileType);
            fileInfoRespVo.setCreateTime(new Date());

            FILE_SET.add(fileInfoRespVo);

            FileCacheVo fileCacheVo = new FileCacheVo();
            fileCacheVo.setFileNo(fileNo);
            fileCacheVo.setFileSuffix(fileType);
            fileCacheVo.setFileName(fileNo + fileType);
            fileCacheVo.setOriginalName(originalFilename);
            fileCacheVo.setPath(tempFile.getPath());

            // 添加预览文档到缓存
            fileViewComponent.addFileToCache(tempFile, fileNo);

            tempFilePathCache.put(fileNo, fileCacheVo);

            return fileInfoRespVo;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException("上传文件失败");
        }
    }

    @Override
    public void viewFile(String fileNo, HttpServletResponse response) {
        response.addHeader("access-control-allow-methods", "GET");
        response.addHeader("access-control-allow-headers", "Content-Type");
        FileCacheVo fileCacheVo = tempFilePathCache.get(fileNo);
        if (fileCacheVo == null) {
            responseFailure("文件不存在!", response);
            return;
        }
        boolean existFile = fileViewComponent.cacheExistFile(fileNo);
        if (!existFile) {
            responseFailure("文件已经不存在!", response);
            return;
        }
        // 预览文档
        fileViewComponent.viewCacheFile(response, fileNo);
    }

    private void responseFailure(String msg, HttpServletResponse response) {
        response.setContentType("application/json; charset=utf-8");
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        try (PrintWriter pw = response.getWriter()) {
            String result = objectMapper.writeValueAsString(R.fail(msg));
            pw.write(result);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
    }
}

前端使用方式

注意:viewFile是接入的后端服务自己接口,本组件不直接提供接口

 axios.get("http://localhost:8081/officePreview/viewFile?fileNo=" + item.fileNo, {responseType: "blob"}).then(res => {
    let type = res.headers['file-type'];
    let blob;
    if (type === "html") {
        blob = new Blob([res.data], {type: 'text/html'});
    } else {
        blob = new Blob([res.data], {type: 'application/pdf'})
    }
    let pdfSrc = window.URL.createObjectURL(blob)
    window.open(pdfSrc)//新窗口打开,借用浏览器查看文档
}).catch(error => {
    alert("预览失败!");
})

标签:fileNo,Office,office,cache,String,file,response,轻量级,SpringBoot
来源: https://www.cnblogs.com/lwjQAQ/p/16644202.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有