2021SC@SDUSC kkfileview(1)

2021SC@SDUSC

项目介绍



项目简介

此项目为文件文档在线预览项目解决方案,对标业内付费产品有【永中office】【office365】【idocv】等,在取得公司高层同意后以Apache协议开源出来反哺社区,
项目地址: kkFileView: 使用spring boot打造文件文档在线预览项目解决方案,支持doc、docx、ppt、pptx、xls、xlsx、zip、rar、mp4、mp3以及众多类文本如txt、html、xml、java、properties、sql、js、md、json、conf、ini、vue、php、py、bat、gitignore等文件在线预览



项目特性



2. 部署运行



1). 物理机或虚拟机上运行



2). Docker容器环境环境运行

docker pull keking/kkfileview

docker run -it -p 8012:8012 keking/kkfileview



3. 项目接入使用

当您的项目内需要预览文件时,只需要调用浏览器打开本项目的预览接口,并传入须要预览文件的url,示例如下:


详细使用说明见 kkFileView使用指南



使用指南

当您的项目内需要预览文件时,只需要调用浏览器打开本项目的预览接口,并传入须要预览文件的url。
注意,如果要预览的url里包含需要转义的特殊字符,如下表格,请使用encodeURIComponent(url)转义

符号 url中转义结果 转义码
+ URL 中+号表示空格 %2B
空格 URL中的空格可以用+号或者编码 %20
/ 分隔目录和子目录 %2F
分隔实际的URL和参数 %3F
% 指定特殊字符 %25
# 表示书签 %23
& URL 中指定的参数间的分隔符 %26
= URL 中指定参数的值 %3D



1. 普通文件下载url预览




2. http/https下载流url预览

很多系统内不是直接暴露文件下载地址,而是请求通过id、code等参数到通过统一的接口,后端通过id或code等参数定位文件,再通过OutputStream输出下载,此时下载url是不带文件后缀名的,预览时需要拿到文件名,传一个参数fullfilename=xxx.xxx来指定文件名,示例如下




3. FTP下载url预览



1). FTP匿名访问

如果要预览的FTP url是可以匿名访问的(不需要用户名密码),则可以直接通过下载url预览,示例如下




2). 非匿名访问,确定只有访问一台FTP服务器

如果预览服务只访问一台FTP服务器,只需要在配置文件中 配置FTP链接信息 ,则可以直接通过下载url预览,示例如下




3). 非匿名访问,不只访问一台FTP服务器

如果预览服务要访问多台FTP服务器,且用户名密码不一致,可以通过在url中加入用户名密码等参数预览(url参数中的优化于配置文件中的),示例如下,


  1. 支持word excel ppt,pdf等办公文档
  2. 支持txt,java,php,py,md,js,css等所有纯文本
  3. 支持zip,rar,jar,tar,gzip等压缩包
  4. 支持jpg,jpeg,png,gif等图片预览(翻转,缩放,镜像)
  5. 支持mp3,mp4,flv等多媒体文件预览
  6. 使用spring boot开发,预览服务搭建部署非常简便
  7. rest接口提供服务,跨平台特性(java,php,python,go,php,....)都支持,应用接入简单方便
  8. 支持普通http/https文件下载url、http/https文件下载流url、ftp下载url等多种预览源
  9. 提供zip,tar.gz发行包,提供一键启动脚本和丰富的配置项,方便部署使用
  10. 提供Docker镜像发行包,方便在容器环境部署
  11. 抽象预览服务接口,方便二次开发,非常方便添加其他类型文件预览支持
  12. 最最重要Apache协议开源,代码pull下来想干嘛就干嘛
  13. 部署指南



    1. 环境要求

  14. Java: 1.8+
  15. OpenOffice或LiberOffice(Windows下已内置,CentOS或Ubuntu下会自动下载安装,MacOS下需要自行安装)
  16. 从 码云发行版本 下载最新版发行包
  17. 解压kkFileView-2.x.x.zip包
  18. 打开解压后文件夹的bin目录,运行startup脚本(Windows下以管理员身份运行startup.bat,Linux以root用户运行startup.sh
  19. 浏览器访问本机8012端口(http://127.0.0.1:8012 )即可看到项目演示用首页
  20. 拉取镜像
  21. 运行
  22. 浏览器访问容器8012端口(http://xxx.xxx.xxx.xxx:8012 )即可看到项目演示用首页
  23. var url = 'http://127.0.0.1:8080/file/test.txt'; //要预览文件的访问地址

  24. window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(previewUrl));

  25. var url = 'http://127.0.0.1:8080/file/test.txt'; //要预览文件的访问地址

  26. window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(url));

  27. var originUrl = 'http://127.0.0.1:8080/filedownload?fileId=1'; //要预览文件的访问地址

  28. var previewUrl = originUrl + '&fullfilename=test.txt'

  29. window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(previewUrl));

  30. var url = 'ftp://127.0.0.1/file/test.txt'; //要预览文件的访问地址

  31. window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(url));

  32. var url = 'ftp://127.0.0.1/file/test.txt'; //要预览文件的访问地址

  33. window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(url));

  34. var originUrl = 'ftp://127.0.0.1/file/test.txt'; //要预览文件的访问地址

  35. var previewUrl = originUrl + '?ftp.username=xx&ftp.password=xx&ftp.control.encoding=xx';

  36. window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(previewUrl));              核心代码:

    package cn.keking.web.controller;
    
    import cn.keking.config.ConfigConstants;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.google.common.collect.ImmutableMap;
    import com.google.common.collect.Lists;
    import cn.keking.model.ReturnResponse;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.util.StreamUtils;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.*;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    import java.util.Objects;
    
    /**
     *
     * @author yudian-it
     * @date 2017/12/1
     */
    @RestController
    public class FileController {
    
        private final Logger logger = LoggerFactory.getLogger(FileController.class);
    
        private final String fileDir = ConfigConstants.getFileDir();
    
        private final String demoDir = "demo";
    
        private final String demoPath = demoDir + File.separator;
    
        @RequestMapping(value = "fileUpload", method = RequestMethod.POST)
        public String fileUpload(@RequestParam("file") MultipartFile file) throws JsonProcessingException {
            // 获取文件名
            String fileName = file.getOriginalFilename();
            //判断是否为IE浏览器的文件名,IE浏览器下文件名会带有盘符信息
            // Check for Unix-style path
            int unixSep = fileName.lastIndexOf('/');
            // Check for Windows-style path
            int winSep = fileName.lastIndexOf('\\');
            // Cut off at latest possible point
            int pos = (Math.max(winSep, unixSep));
            if (pos != -1)  {
                fileName = fileName.substring(pos + 1);
            }
            // 判断是否存在同名文件
            if (existsFile(fileName)) {
                return new ObjectMapper().writeValueAsString(new ReturnResponse(1, "存在同名文件,请先删除原有文件再次上传", null));
            }
            File outFile = new File(fileDir + demoPath);
            if (!outFile.exists()) {
                outFile.mkdirs();
            }
            logger.info("上传文件:{}", fileDir + demoPath + fileName);
            try(InputStream in = file.getInputStream(); OutputStream out = new FileOutputStream(fileDir + demoPath + fileName)) {
                StreamUtils.copy(in, out);
                return new ObjectMapper().writeValueAsString(new ReturnResponse(0, "SUCCESS", null));
            } catch (IOException e) {
                logger.error("文件上传失败", e);
                return new ObjectMapper().writeValueAsString(new ReturnResponse(1, "FAILURE", null));
            }
        }
    
        @RequestMapping(value = "deleteFile", method = RequestMethod.GET)
        public String deleteFile(String fileName) throws JsonProcessingException {
            if (fileName.contains("/")) {
                fileName = fileName.substring(fileName.lastIndexOf("/") + 1);
            }
            File file = new File(fileDir + demoPath + fileName);
            logger.info("删除文件:{}", file.getAbsolutePath());
            if (file.exists()) {
                file.delete();
            }
            return new ObjectMapper().writeValueAsString(new ReturnResponse(0, "SUCCESS", null));
        }
    
        @RequestMapping(value = "listFiles", method = RequestMethod.GET)
        public String getFiles() throws JsonProcessingException {
            List> list = Lists.newArrayList();
            File file = new File(fileDir + demoPath);
            if (file.exists()) {
                Arrays.stream(Objects.requireNonNull(file.listFiles())).forEach(file1 -> list.add(ImmutableMap.of("fileName", demoDir + "/" + file1.getName())));
            }
            return new ObjectMapper().writeValueAsString(list);
        }
    
        private boolean existsFile(String fileName) {
            File file = new File(fileDir + demoPath + fileName);
            return file.exists();
        }
    }

                                   

你可能感兴趣的:(java)