一般管理系统都有文件上传功能,基于此一般会诞生一个需求:用户需要在线预览自己上传的文件。需求很合理,但是没那么好做,原因在于浏览器默认支持图片、pdf等少量格式预览,而实际情况是你并不能要求用户只上传pdf,对于可能excel和word是非常多的。所以在线预览文件是必不可少的了。
前置解释:
1、 文件地址预览:上传文件后可以获取文件的完整地址的方式,这里分为两种:
① 开放文件:比如阿里云对象存储COS,访问的地址其实就是真正的文件地址;
② 其他文件地址:比如文件服务器的部分情况,这种地址一般存在防盗链之类的,并不属于真正的开放文件。
2、文件下载流:文件上传后获得的路径时后台接口地址,并不能直接获取文件,比如MongoDB的文件上传,这种文件一般时属于私密文件的,虽然一般也可直接通过接口地址的方式访问文件,但是很有可能开发者会在后来对你的访问进行拦截。
此种方案为最常见的,不多做描述。
文件路径 + 下载流的PDF、HTML、图片等文件预览,这个主要是浏览器自带的功能。
方便、简单
可预览文件类型较少,常见的office类的word、excel是不支持的。
http://view.officeapps.live.com/op/view.aspx?src=<Document Location>
前面是固定的,到 src 后面跟的是自己文件的路径,例图如下:

开放路径的office类文件。
开放路径:常见的如腾讯阿里的对象存储 COS;
office类文件:比如常见的word、excel、ppt等其他office系的文件。
简单,不需要做过多处理,只要前端在访问路径前面加一段路径即可,支持大部分文件预览。
因为适用范围限制,如果文件路径为非开放(下载流、有防盗链等),是没办法获取到文件进行展示的。
参考文档:kkFileView使用指南

根据官方的宣传,基本上我们能平时接触到的文件格式都支持,还支持文件地址 + 文件下载流的文件方式。
支持文件类型多样,服务部署后,前端只需简单操作即可完成,还能对文件进行水印等操作。
① 需要单独部署服务;
② 真实使用比宣传难。
其实就kkFileView的名气还是挺大的,就我目前使用的情况而言,确实也挺好的,但是缺点也不少,比如使用中的缺陷,而且这个项目的社区活跃性一般,去gitee上面很多issue并没人回答解决,也正是因为这样,才写下这个博客,记录下一些问题,也希望能帮助到小伙伴们。
下载地址:gitee开源项目kkFileView

本博客写作于2022.02.23,此时最新版本为4.0,版本分为Windows和Linux(MacOS)的,Windows的就不多说了,大家自行安装下一步吧,接下来的内容基于centos7的服务器进行安装操作。
下载好版本,解压之后直接上传到服务器(我是上传到 /opt目录,如果不熟悉的小伙伴可以按照我的目录)。

大致目录如上图,注意我划线的两个sh,后面会用到。下附一张kkFileView官网的运行方式

此时我们已经完成下载和上传步骤,并知晓官网上的运行方式
①切换至bin目录下,命令:cd /opt/kkFileView-4.0.0/bin;
②执行startup.sh,命令:./startup.sh;
由于服务器已经安装过了,我就不截图了,说说步骤,比较简单,大家看看就行。如果执行
.sh文件提示没有权限,执行下chmod 777 *.sh
完成上述步骤,按照官网的意思应该是可以运行了,但是大家注意看终端打印(或者访问地址)肯定是不能访问的,明显就是报错了,怎么看日志呢?注意上面给大家截图的两个.sh文件。
③查看日志,命令:./showlog.sh,日志很简单可以看出来,就是一个问题,没有office插件,并没有像官网说的Centos会自动下载(Windows没事,反正我的centos7肯定没有);
④下载office插件:官网说的可以OpenOffice或者LiberOffice,但是4.0版本的更新日志说:底层集成OpenOffice替换为LibreOffice,Office文件兼容性增强,预览效果提升,那肯定安装LiberOffice了。
a. LiberOffice下载地址:LiberOffice官网(注意版本,选择自己适合的版本,这个地址进去是7.3.1)
因为下载可能比较慢,给大家准备了百度网盘和阿里网盘的分享下载,自取(版本7.3.1):
链接:https://pan.baidu.com/s/1N7rtuoYTWok7IUtSja7tng?pwd=0mx0
提取码:0mx0
「LibreOffice_7.3.1_Linux_...m_langpack_zh-CN」等文件
https://www.aliyundrive.com/s/njLZXccnxRD

上图有个中文语言包,我看网上有人说需要,最好还是装上,避免部分中文不支持
反正我没装,知道的小伙伴麻烦给我留言(我估计应该是预览的时候对中文支持比较好,但是我没安装,好像没啥问题)。下载有点慢,多等一会,或者下个迅雷下载比较快。
以下安装参考博客:centos 安装 LibreOffice
b. LiberOffice上传服务器,此步略过,我还是放在/opt目录的。
c. 安装LiberOffice:上传不代表可以用了,还需要安装
命令:yum install /opt/LibreOffice_7.3.1.3_Linux_x86-64_rpm/RPMS/*.rpm
d. 配置office插件地址。此处需要介绍到kkFileView的配置文件,基本配置参考官方文档:配置说明

大概28行左右, office.home = /opt/libreoffice7.3,注意这个路径是安装后的路径,不是源文件。

e. 再次启动,cd /opt/kkFileView-4.0.0/bin 执行命令 ./startup.sh,这次就成功了。
至此,kkFileView基本启动完成,如果有失败的小伙伴,请
./showlog.sh查看日志,但这只是一个开始。
官网:使用指南
根据自己的情况选择使用方式即可。
官网常见问题:常见问题
这个问题官网的常见问题就有,但是并不能解决问题,但是提供了一个思路:这个就是字体的问题。我去网上下了很多字体都不行,后来在gitee的评论里看到一个兄弟的解决方案:把windows电脑的字体全部上传。操作步骤如下:
① 控制面板 --> 外观和个性化 --> 字体 选择所有字体放在一个文件夹;
② 上传字体文件夹到/usr/share/fonts目录下,然后依次执行mkfontscale 、mkfontdir 、fc-cache使字体生效;
然后访问,基本实现正常预览。
这个问题主要在预览PDF的时候出现,默认使用图片预览的方式,问题还比较少。
我现在文件基本可以预览,就出现了增值税发票预览出错,暂时没有解决办法,之后有法子就来补充,或者有小伙伴知道的留言一下。 解决办法建下面第5节自立更生,手动编译

在application.properties配置文件可以配置固定的水印,官网也有动态水印的解决办法,但是一定要注意水印是在页面上不是文件上,利用浏览器打印可以打印出水印。但是切换到pdf,利用pdf.js打印是没有水印的。
在application.properties配置文件可以配置缓存清除时机,但是缓存有一点问题就是同名文件可能缓存更新不过来,不如你有个文件a.txt,但是你修改了这文件,极有可能显示的还是原来的文件。我的解决办法:
① Redis缓存,在application.properties配置文件里设置Redis缓存,减轻本地缓存的压力;
② 预览文件的时候,文件名称加上系统内文件的ID,这样重名文件但是ID不一样,就不会出现缓存问题。
附一个官网下载流预览文件的方式:
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/js-base64@3.6.0/base64.min.js"></script>
var originUrl = 'http://127.0.0.1:8080/filedownload?fileId=1'; //要预览文件的访问地址
var previewUrl = originUrl + '&fullfilename=test.txt'
window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(Base64.encode(previewUrl)));
这有一个问题就是所有的IP和地址都在前端写的,虽然没有什么问题,但是如果你想做成可配置化的IP,那地址最好在后端来补全,前端做一下跳转就行,这个预览地址基本就是采用base64 + 特殊字符转义的方式,但是水印是将需要转换的内容(ASCII码形式之外的内容),用十六进制表示法转换出来(以下代码借用Hutool的工具):
/**
* 加密文件路径
*
* @param text 路径或文本
* @return 返回
*/
private String encodeUrl(String text) {
StringBuilder builder = new StringBuilder();
// 这个地方是配置的特殊字符转义
String specialChar = configService.selectConfigByKey(ConfigConstant.FILE_SPECIAL_CHAR);
if (StrUtil.isBlank(specialChar)) {
specialChar = "+/";
}
byte[] specialCharArr = StrUtil.bytes(specialChar);
String encode = Base64.encode(text);
byte[] bytes = StrUtil.bytes(encode);
if (ArrayUtil.isNotEmpty(bytes)) {
for (byte aByte : bytes) {
if (ArrayUtil.contains(specialCharArr, aByte)) {
builder.append("%");
HexUtil.appendHex(builder, aByte, false);
} else {
builder.append(new java.lang.String(new byte[]{aByte}));
}
}
}
return builder.toString();
}
/** 水印加密 */
URLUtil.encode(StrUtil.emptyIfNull(watermark))
不得不说kkFileView真的是一个非常不错的项目,因为他是SpringBoot开发的,现在不满足需求了,那就源码拉下来自己开发呗。官网编译方法:编译方法
编译jar包自取(以后每次修改都在这里)
2022/04/05
链接:https://pan.baidu.com/s/13WHLy9H4cflCqQhqpbCHRQ?pwd=7jdz
提取码:7jdz
「myFileView」https://www.aliyundrive.com/s/rrzJiNwcrX6
2022/04/05 拉下最新代码(未发布的4.1版本,此版本采用了最新的pdf.js,界面好看了很多,还可配置顶部工具栏),修改点:无;解决问题:增值税发票PDF预览问题

我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A