文件文档在线预览转换解决方案和应用

文章目录

  • Java Word转PDF文件方案评测
  • 一、kkFileView应用场景一:官网原始部署与应用
  • 二、kkFileView应用场景二:编译、自定义制作docker镜像部署
  • 三、kkfileview预览pdf文件以及关键词高亮和定位


Java Word转PDF文件方案评测

Word转PDF网上常见的方案5种,aspose-words、docx4j、openoffice、poi、spire.doc。
方案对比说明
提示:上面方案仅限于Windows操作系统,Linux OS实测Word转换PDF时,docx4j会报错、poi 文档内容会出现乱码(应该是系统需要安装font字体)。

基于项目环境是Linux Os,最终放弃上面所有方案,选择Apache协议开源的kkFileView,官网
kkFileView为文件文档在线预览项目解决方案,对标业内付费产品有【永中office】【office365】【idocv】等,Apache协议开源项目,该项目使用流行的spring boot搭建,易上手和部署,基本支持主流办公文档的在线预览,如doc,docx,Excel,pdf,txt,zip,rar,图片等。
以下篇幅将介绍 kkFileView开源项目的不同的应用场景。

一、kkFileView应用场景一:官网原始部署与应用

  1. 环境要求 #
    Java: 1.8+
    LibreOffice或OpenOffice(Windows下已内置,CentOS或Ubuntu下会自动下载安装,MacOS下需要自行安装)

  2. 物理机或虚拟机上运行 #
    1)从 码云发行版本 下载最新版发行包
    项目目录说明:
    文件文档在线预览转换解决方案和应用_第1张图片
    Docker目录:构建kkFileView JDK环境和Docker制作文件,Docker制作文件(Dockerfile)执行操作:
    1)引入ubuntu:20.04
    2)内置一些常用中文字体
    3)安装language-pack-zh*
    4)下载kkview.cn官网server-jre-8u251-linux-x64.tar.gz 即jdk1.8环境
    5)安装 libreoffice
    6)清理临时文件
    7)设置JDK、Lang等配置和CMD命令

Server目录:kkFileView 服务目录
lib:第三方转码jar包
LibreOfficePortable:LibreOffice 便携版,存放LibreOffice关联的环境文件
src:kkFileView 后台服务源代码
Target:kkFileView 后台服务编译后生成可执行包(kkFileView-4.4.0-SNAPSHOT.jar、.tar.gz、.zip等)
pom.xml文件:服务MVN构建文件

2)Idea开发工具 重新执行mvn命令,编译kkFileView服务
文件文档在线预览转换解决方案和应用_第2张图片
文件文档在线预览转换解决方案和应用_第3张图片
3)解压kkFileView-x.x.x文件(Windows用.zip包,Linux/MacOS用.tar.gz包)
打开解压后文件夹的bin目录,运行startup脚本(Windows下以管理员身份运行startup.bat,Linux以root用户运行startup.sh)
4)打开浏览器访问本机8012端口 http://127.0.0.1:8012 即可看到项目演示用首页

  1. Docker上运行 #
    拉取镜像 #
    docker pull keking/kkfileview:4.1.0
    #网络环境不方便访问Docker中央仓库
    wget http://kkfileview.keking.cn/kkFileView-4.1.0-docker.tar
    docker load -i kkFileView-4.1.0-docker.tar

运行 #
docker run -it -p 8012:8012 keking/kkfileview:4.1.0
浏览器访问容器8012端口 http://127.0.0.1:8012 即可看到项目演示用首页

  1. 项目接入使用
    当您的项目内需要预览文件时,只需要调用浏览器打开本项目的预览接口,并传入须要预览文件的url,示例如下:
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/base64.min.js"></script>

var url = 'http://127.0.0.1:8080/file/test.txt'; //要预览文件的访问地址
window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(Base64.encode(previewUrl)));

二、kkFileView应用场景二:编译、自定义制作docker镜像部署

前提:安装docker
1)Idea开发工具 重新执行mvn命令,编译kkFileView服务,最终生成kkFileView-4.4.0-SNAPSHOT.tar.gz
文件文档在线预览转换解决方案和应用_第4张图片
文件文档在线预览转换解决方案和应用_第5张图片
2)服务器端(linux主机)编写Docerfile、构建、运行
创建merakkkfileview目录、上传Dockerfile和kkFileView-4.4.0-SNAPSHOT.tar.gz

[root@iZm5e1mrbokrl04np8nv1mZ merakkkfileview]# mkdir merakkkfileview 
[root@iZm5e1mrbokrl04np8nv1mZ merakkkfileview]# pwd 
/home/merak/merakkkfileview 
[root@iZm5e1mrbokrl04np8nv1mZ merakkkfileview]# ll 
total 291960 
-rw-r--r-- 1 root root 371 Aug 23 16:35 Dockerfile 
-rw-r--r-- 1 root root 298959899 Aug 23 16:34 kkFileView-4.4.0-SNAPSHOT.tar.gz 

编辑Dockerfile文件

[root@iZm5e1mrbokrl04np8nv1mZ merakkkfileview]# cat Dockerfile 
FROM keking/kkfileview-jdk:latest 
MAINTAINER chenjh "[email protected]" 
ADD ./kkFileView-*.tar.gz /opt/ 
ENV KKFILEVIEW_BIN_FOLDER /opt/kkFileView-4.4.0-SNAPSHOT/bin 
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dspring.config.location=/opt/kkFileView-4.4.0-SNAPSHOT/config/application.properties","-jar","/opt/kkFileView-4.4.0-SNAPSHOT/bin/kkFileView-4.4.0-SNAPSHOT.jar"] 

构建和查询构建镜像

[root@iZm5e1mrbokrl04np8nv1mZ]# docker build -t merakkkfileview:1.0 .
[root@iZm5e1mrbokrl04np8nv1mZ]# docker images | grep merakkkfileview 
merakkkfileview 1.0 ebdf069b5ece 33 minutes ago 1.65GB 

运行Docker

[root@iZm5e1mrbokrl04np8nv1mZ]# docker run -itd -p 11182:8012 merakkkfileview:1.0

将Docker内kkfileview默认端口8012映射成外部端口11182
检查是否正常

[root@iZm5e1mrbokrl04np8nv1mZ ]# docker ps | grep merakkkfileview 
5da1a5c602ff merakkkfileview:1.0 "java -Dfile.encodin…" 28 minutes ago Up 28 minutes 0.0.0.0:11182->8012/tcp, :::11182->8012/tcp

3)首页访问与测试 http://ip:11182/
文件文档在线预览转换解决方案和应用_第6张图片

三、kkfileview预览pdf文件以及关键词高亮和定位

1、kkfileview源代码前后端代码改造

kkfileview通过OnlinePreviewController.java业务类@GetMapping( “/onlinePreview”)接口实现文件的在线浏览。
onlinePreview接口:url参数获取原始文件路径 ; Model :Model层接收数据且向View层渲染数据;HttpServletRequest:接收前端浏览器请求信息。
所以我们需要增加参数keyword:接收前台高亮搜索的关键词。

  /**
     * 文件在线浏览
     * @param url     原始文件路径
     * @param keyword 接收前台高亮搜索的关键词
     * @param model   Model层接收数据且向View层渲染数据
     * @param req     接收前端浏览器请求信息
     * @return
     */
    @GetMapping( "/onlinePreview")
    public String onlinePreview(String url, String keyword, Model model, HttpServletRequest req) {
        String fileUrl;
        try {
            fileUrl = WebUtils.decodeUrl(url);
        } catch (Exception ex) {
            String errorMsg = String.format(BASE64_DECODE_ERROR_MSG, "url");
            return otherFilePreview.notSupportedFile(model, errorMsg);
        }
        FileAttribute fileAttribute = fileHandlerService.getFileAttribute(fileUrl, req);
        model.addAttribute("file", fileAttribute);
        model.addAttribute("keyword", keyword);  // 将接收前台高亮搜索的关键词存储到model中
        FilePreview filePreview = previewFactory.get(fileAttribute);
        logger.info("预览文件url:{},previewType:{}", fileUrl, fileAttribute.getType());
        return filePreview.filePreviewHandle(fileUrl, model, fileAttribute);
    }

web/pdf.ftl文件 获取关键词,传递给pdf.js,pdf.ftl文件:

<script type="text/javascript">
    var url = '${finalUrl}';
    var baseUrl = '${baseUrl}'.endsWith('/') ? '${baseUrl}' : '${baseUrl}' + '/';
    if (!url.startsWith(baseUrl)) {
        url = baseUrl + 'getCorsFile?urlPath=' + encodeURIComponent(Base64.encode(url));
    }
    // 首先从我们的model中获取keyword
    var keyword = '${keyword}';
    document.getElementsByTagName('iframe')[0].src = "${baseUrl}pdfjs/web/viewer.html?file=" + encodeURIComponent(url) + "&disablepresentationmode=${pdfPresentationModeDisable}&disableopenfile=${pdfOpenFileDisable}&disableprint=${pdfPrintDisable}&disabledownload=${pdfDownloadDisable}&disablebookmark=${pdfBookmarkDisable}&disableediting=${pdfDisableEditing}" + "&keyword="+ keyword;
    document.getElementsByTagName('iframe')[0].height = document.documentElement.clientHeight - 10;

static/pdfjs/viewer.js文件,修改 setInitialView(storedHash) {} 内置函数:

setInitialView(storedHash) {
   //原始代码----开始
    let {
      rotation,
      sidebarView,
      scrollMode,
      spreadMode
    } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    const setRotation = angle => {
      if ((0, _ui_utils.isValidRotation)(angle)) {
        this.pdfViewer.pagesRotation = angle;
      }
    };
    const setViewerModes = (scroll, spread) => {
      if ((0, _ui_utils.isValidScrollMode)(scroll)) {
        this.pdfViewer.scrollMode = scroll;
      }
      if ((0, _ui_utils.isValidSpreadMode)(spread)) {
        this.pdfViewer.spreadMode = spread;
      }
    };
    this.isInitialViewSet = true;
    this.pdfSidebar?.setInitialView(sidebarView);
    setViewerModes(scrollMode, spreadMode);
    if (this.initialBookmark) {
      setRotation(this.initialRotation);
      delete this.initialRotation;
      this.pdfLinkService.setHash(this.initialBookmark);
      this.initialBookmark = null;
    } else if (storedHash) {
      setRotation(rotation);
      this.pdfLinkService.setHash(storedHash);
    }
    this.toolbar?.setPageNumber(this.pdfViewer.currentPageNumber, this.pdfViewer.currentPageLabel);
    this.secondaryToolbar?.setPageNumber(this.pdfViewer.currentPageNumber);
    if (!this.pdfViewer.currentScaleValue) {
      this.pdfViewer.currentScaleValue = _ui_utils.DEFAULT_SCALE_VALUE;
    }
    //原始代码----结束

    //高亮需要加入的代码:获取keyword、回写以及触发高亮点击按钮
    const queryString = document.location.search.slice(1);
    const m = /(^|&)keyword=([^&]*)/.exec(queryString);
    const keyword = m ? decodeURIComponent(m[2]) : "";
    console.log("keyword", keyword);
    //对查询输入框进行赋值
    document.getElementById("findInput").value=keyword;
    //点击高亮按钮实现高亮显示关键词
    document.getElementById("findHighlightAll").click();*
  },

2.重新编译、自定义制作docker镜像部(具体过程同“kkFileView应用场景二:编译、自定义制作docker镜像部署”一致。

3.运行效果:
文件文档在线预览转换解决方案和应用_第7张图片

PS
kkfileview官网
kkfileview文档
gitee源码

kkfileview配置-server\src\main\config\application.properties:

#######################################不可动态配置,需要重启生效#######################################
server.port = ${KK_SERVER_PORT:11182}
server.servlet.context-path= ${KK_CONTEXT_PATH:/}
server.servlet.encoding.charset = utf-8
#启用GZIP压缩功能
server.compression.enable= true
#允许压缩的响应缓冲区最小字节数,默认2048
server.compression.min-response-size = 2048
#压缩格式
server.compression.mime-types=application/javascript,text/css,application/json,application/xml,text/html,text/xml,text/plain,font/woff,application/font-woff,font/eot,image/svg+xml,image/x-icon
# 文件上传限制前端
spring.servlet.multipart.max-file-size=500MB
#文件上传限制
spring.servlet.multipart.max-request-size=500MB
## Freemarker 配置
spring.freemarker.template-loader-path = classpath:/web/
spring.freemarker.cache = false
spring.freemarker.charset = UTF-8
spring.freemarker.check-template-location = true
spring.freemarker.content-type = text/html
spring.freemarker.expose-request-attributes = true
spring.freemarker.expose-session-attributes = true
spring.freemarker.request-context-attribute = request
spring.freemarker.suffix = .ftl

# office设置
#openoffice或LibreOffice  home路径
#office.home = C:\\Program Files (x86)\\OpenOffice 4
office.home = ${KK_OFFICE_HOME:default}
## office转换服务的进程数,默认开启两个进程
office.plugin.server.ports = 2001,2002
## office 转换服务 task 超时时间,默认五分钟
office.plugin.task.timeout = 5m
#生成限制 默认不限制 使用方法 (1-5)
office.pagerange = ${KK_OFFICE_PAGERANGE:false}
#生成水印 默认不启用 使用方法 (kkFileView)
office.watermark  = ${KK_OFFICE_WATERMARK:false}
#OFFICE JPEG图片压缩
office.quality = ${KK_OFFICE_QUALITY:80}
#图像分辨率限制
office.maximageresolution = ${KK_OFFICE_MAXIMAGERESOLUTION:150}
#导出书签
office.exportbookmarks = ${KK_OFFICE_EXPORTBOOKMARKS:true}
#批注作为PDF的注释
office.exportnotes = ${KK_OFFICE_EXPORTNOTES:true}
#加密文档 生成的PDF文档 添加密码(密码为加密文档的密码)
office.documentopenpasswords = ${KK_OFFICE_DOCUMENTOPENPASSWORD:true}
#xlsx格式前端解析
office.type.web = ${KK_OFFICE_TYPE_WEB:web}


# 其他核心设置
#预览生成资源路径(默认为打包根路径下的file目录下)
#file.dir = D:\\kkFileview\\
file.dir = ${KK_FILE_DIR:default}
#允许预览的本地文件夹 默认不允许任何本地文件被预览
#WINDOWS参考 local.preview.dir =  \D:\\kkFileview\\1\\1.txt (注意前面必须添加反斜杠)
#LINUX参考   local.preview.dir =  /opt/1.txt (注意前面必须是正斜杠)
#使用方法 windows  file://d:/1/1.txt  linux file:/opt/1/1.txt
#file 协议参考:https://datatracker.ietf.org/doc/html/rfc8089
local.preview.dir = ${KK_LOCAL_PREVIEW_DIR:default}
#是否启用缓存
cache.enabled = ${KK_CACHE_ENABLED:true}
#缓存实现类型,不配默认为内嵌RocksDB(type = default)实现,可配置为redis(type = redis)实现(需要配置spring.redisson.address等参数)和 JDK 内置对象实现(type = jdk),
cache.type =  ${KK_CACHE_TYPE:jdk}
#redis连接,只有当cache.type = redis时才有用
spring.redisson.address = ${KK_SPRING_REDISSON_ADDRESS:127.0.0.1:6379}
spring.redisson.password = ${KK_SPRING_REDISSON_PASSWORD:}
#缓存是否自动清理 true 为开启,注释掉或其他值都为关闭
cache.clean.enabled = ${KK_CACHE_CLEAN_ENABLED:true}
#缓存自动清理时间,cache.clean.enabled = true时才有用,cron表达式,基于Quartz cron
cache.clean.cron = ${KK_CACHE_CLEAN_CRON:0 0 3 * * ?}
#######################################可在运行时动态配置#######################################
#提供预览服务的地址,默认从请求url读,如果使用nginx等反向代理,需要手动设置
#base.url = https://file.keking.cn
base.url = ${KK_BASE_URL:default}
#信任站点,多个用','隔开,设置了之后,会限制只能预览来自信任站点列表的文件,默认不限制
#trust.host = kkview.cn
trust.host = ${KK_TRUST_HOST:default}
#文本类型,默认如下,可自定义添加
simText = ${KK_SIMTEXT:txt,html,htm,asp,jsp,xml,json,properties,md,gitignore,log,java,py,c,cpp,sql,sh,bat,m,bas,prg,cmd}


#FTP模块设置
#预览源为FTP时 FTP用户名,可在ftp url后面加参数ftp.username=ftpuser指定,不指定默认用配置的
ftp.username = ${KK_FTP_USERNAME:ftpuser}
#预览源为FTP时 FTP密码,可在ftp url后面加参数ftp.password=123456指定,不指定默认用配置的
ftp.password = ${KK_FTP_PASSWORD:123456}
#预览源为FTP时, FTP连接默认ControlEncoding(根据FTP服务器操作系统选择,Linux一般为UTF-8,Windows一般为GBK),可在ftp url后面加参数ftp.control.encoding=UTF-8指定,不指定默认用配置的
ftp.control.encoding = ${KK_FTP_CONTROL_ENCODING:UTF-8}

#视频设置
#多媒体类型,默认如下,可自定义添加
media = ${KK_MEDIA:mp3,wav,mp4,flv}
#是否开启多媒体类型转视频格式转换,目前可转换视频格式有:avi,mov,wmv,3gp,rm
#请谨慎开启此功能,建议异步调用添加到处理队列,并且增加任务队列处理线程,防止视频转换占用完线程资源,转换比较耗费时间,并且控制了只能串行处理转换任务
media.convert.disable = ${KK_MEDIA_CONVERT_DISABLE:false}
#支持转换的视频类型
convertMedias = ${KK_CONVERTMEDIAS:avi,mov,wmv,mkv,3gp,rm}



#PDF预览模块设置
#配置PDF文件生成图片的像素大小,dpi 越高,图片质量越清晰,同时也会消耗更多的计算资源。
pdf2jpg.dpi = ${KK_PDF2JPG_DPI:144}
#是否禁止演示模式
pdf.presentationMode.disable = ${KK_PDF_PRESENTATION_MODE_DISABLE:true}
#是否禁止打开文件
pdf.openFile.disable = ${KK_PDF_OPEN_FILE_DISABLE:true}
#是否禁止打印转换生成的pdf文件
pdf.print.disable = ${KK_PDF_PRINT_DISABLE:true}
#是否禁止下载转换生成的pdf文件
pdf.download.disable = ${KK_PDF_DOWNLOAD_DISABLE:true}
#是否禁止bookmark
pdf.bookmark.disable = ${KK_PDF_BOOKMARK_DISABLE:true}
#是否禁止签名
pdf.disable.editing = ${KK_PDF_DISABLE_EDITING:false}
#office类型文档(word ppt)样式,默认为图片(image),可配置为pdf(预览时也有按钮切换)
office.preview.type = ${KK_OFFICE_PREVIEW_TYPE:image}
#是否关闭office预览切换开关,默认为false,可配置为true关闭
office.preview.switch.disabled = ${KK_OFFICE_PREVIEW_SWITCH_DISABLED:false}


#水印内容
#例:watermark.txt = ${WATERMARK_TXT:凯京科技内部文件,严禁外泄}
#如需取消水印,内容设置为空即可,例:watermark.txt = ${WATERMARK_TXT:}
watermark.txt = ${WATERMARK_TXT:}
#水印x轴间隔
watermark.x.space = ${WATERMARK_X_SPACE:10}
#水印y轴间隔
watermark.y.space = ${WATERMARK_Y_SPACE:10}
#水印字体
watermark.font = ${WATERMARK_FONT:微软雅黑}
#水印字体大小
watermark.fontsize = ${WATERMARK_FONTSIZE:18px}
#水印字体颜色
watermark.color = ${WATERMARK_COLOR:black}
#水印透明度,要求设置在大于等于0.005,小于1
watermark.alpha = ${WATERMARK_ALPHA:0.2}
#水印宽度
watermark.width = ${WATERMARK_WIDTH:180}
#水印高度
watermark.height = ${WATERMARK_HEIGHT:80}
#水印倾斜度数,要求设置在大于等于0,小于90
watermark.angle = ${WATERMARK_ANGLE:10}


#首页功能设置
#是否禁用首页文件上传
file.upload.disable = ${KK_FILE_UPLOAD_ENABLED:false}
# 备案信息,默认为空
beian = ${KK_BEIAN:default}
#禁止上传类型
prohibit = ${KK_PROHIBIT:exe,dll,dat}
#启用验证码删除文件 默认关闭
delete.captcha= ${KK_DELETE_CAPTCHA:false}
#删除密码
delete.password = ${KK_DELETE_PASSWORD:123456}
#删除 转换后OFFICE、CAD、TIFF、压缩包源文件 默认开启 节约磁盘空间
delete.source.file = ${KK_DELETE_SOURCE_FILE:true}



#Tif类型设置
#Tif类型图片浏览模式:tif(利用前端js插件浏览);jpg(转换为jpg后前端显示);pdf(转换为pdf后显示,便于打印)
tif.preview.type = ${KK_TIF_PREVIEW_TYPE:tif}

#Cad类型设置
#Cad类型图片浏览模式:tif(利用前端js插件浏览);svg(转换为svg显示);pdf(转换为pdf后显示,便于打印)
cad.preview.type = ${KK_CAD_PREVIEW_TYPE:svg}
#Cad转换超时设置
cad.timeout =${KK_CAD_TIMEOUT:90}
#Cad转换线程设置
cad.thread =${KK_CAD_THREAD:5}

你可能感兴趣的:(技术架构,开源框架,java,文档转换,文件在线浏览,高亮,word转换pdf)