Android端预览文件(docx,pptx,xlsx,excel,pdf)的终极方案 KKFileView

138 阅读3分钟

Android端预览文件的痛点

Android中预览PDF文件看似一个很简单的需求,其实在Android碎片化的版本和众多品牌中实则很难统一,更是难兼容。

简单说一下Android中打开PDF文件的几种方式

  1. 通过外部应用打开项目内文件,如WPS。这种虽然开发省事但遇到一些不太熟悉手机的用户会经常打不开文件。Android开发总所周知,通过Intent打开外部应用。如果有相同功能的应用会有弹窗列表来选择其中某一个,通过仅一次或总是的方式打开。点击总是的话,当这个应用卸载就会出问题。点击仅一次的话,下次打开文件还会弹出这个列表,操作未免有些繁琐。

  2. 在项目内打开。相比通过外部应用打开这种方案在用户体验上更好一些,但要么需要收费要么需要集成到项目中做一系列开发,比较麻烦。一些开源的Android端的预览项目也好些年不更新了,出了问题看源码也费劲。

这我就要推荐只需要服务端简单部署,Android只需要拼接下Url,就能在项目内预览的终极方案KKFileView,且开源免费。官网kkFileView - 在线文件预览

KKFileView

这是Windows发布包解压后的文件,可用于Android端本地测试

image.png

双击bin目录下的startup.bat,无法运行常识管理员权限运行或者重启电脑

image.png

运行后会挂起一个cmd窗口

image.png

然后就可以在浏览器中访问这个本地的解析服务,地址 http://127.0.0.1:8012

image.png

在Android中通过WebView加载Url的方式去解析PDF做到项目内在线浏览

1.模拟器中访问本地服务
模拟器中需要使用 http://10.0.2.2:8012 这个地址去拼接,http://10.0.2.2:8012/onlinePreview?url= + 线上文件地址。如果线上地址是stream流需要增加 &fullfilename=文件名 , stream解析的完整地址为http://10.0.2.2:8012/onlinePreview?url= + 线上文件地址+?fullfilename=文件名。文件名必须是以pdf,docx等文档格式结尾的文件名。如果不是stream流的形式则不需要增加 ?fullfilename。地址需要用base64和Uri.encode编码。完整代码如下:
mBrowserView?.loadUrl("http://10.0.2.2:8012/onlinePreview?url=${encodeFileUrl("http://****.***.**:*****/download/$id/stream",file.name)}")


fun encodeFileUrl(baseUrl: String,fullfilename: String=""): String {
    val base64 = "${baseUrl}?fullfilename=$fullfilename"
    return Uri.encode(Base64.encodeToString(base64.toByteArray(), Base64.NO_WRAP))
}

2.真机访问本地服务
代码都一样只是需要更换IP地址,打开cmd命令窗口输入命令ipconfig查看ipv4的地址,再确保手机Wifi的IP地址和电脑的ipv4地址相同,处于同一网络环境下。将解析地址更换为ipv4地址即可。

image.png

兼容性问题
Android端通过WebView加载出来的PDF默认是图片样式,图片会大于屏幕无法完整显示。需要加入head meate 的 viewport。具体代码:
/**
 * 完成加载网页
 */
override fun onPageFinished(view: WebView, url: String) {
    val js = "javascript:(function(){" +
            "var meta = document.createElement('meta');" +
            "meta.name='viewport';" +
            "meta.content='width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=yes';" +
            "document.getElementsByTagName('head')[0].appendChild(meta);" +
            "})()"
    view.evaluateJavascript(js, null)


    // 同时强制图片自适应(针对 kkFileView 图片预览)
    val imgCss = "javascript:(function(){" +
            "var style = document.createElement('style');" +
            "style.innerHTML = 'img, .picture-img { max-width:100% !important; height:auto !important; width:auto !important; } body{margin:0 !important;}';" +
            "document.head.appendChild(style);" +
            "})()"
    view.evaluateJavascript(imgCss, null)
}
默认会显示一个PDF和JPG的切换开关,上面的兼容代码设置后这个按钮会无法适配大小。不需要这个开关需要在服务端关掉。具体在config->application.properties 中的 office.preview.switch.disabled = ${KK_OFFICE_PREVIEW_SWITCH_DISABLED:false}将最后这个false修改为true即可。
结语
最后的服务发行包我就不放了,可以自己去github下载源码编译。或者加入KKFileView的知识星球获取(需要99元),地址 KK开源社区-知识星球。 建议去知识星球获取,毕竟省事而且好的项目也需要付出精力去维护的。况且公司能报销没必要给公司省钱。