更新记录

2.0.7(2023-09-17)

紧急修复安卓原生预览灰屏

2.0.6(2023-09-11)

优化初始化接口,在打开文档时调用。

2.0.5(2023-07-21)

bug 及功能优化

  • 修复部分引擎页面跳转问题
  • 优化 SDK 加载流程
  • 文件打开默认不会自动跳转上次打开位置,需要通过 openFileReader 接口参数启用该功能
  • 优化 SDK 重新可用逻辑,资源包消耗完后绑定新资源包可以快速重新生效

新增功能

  • 增加安卓组件集成功能
查看更多

平台兼容性

Android Android CPU类型 iOS
适用版本区间:5.0 - 12.0 armeabi-v7a:未测试,arm64-v8a:未测试,x86:未测试 适用版本区间:9 - 16

原生插件通用使用流程:

  1. 购买插件,选择该插件绑定的项目。
  2. 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
  3. 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
  4. 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
  5. 开发完毕后正式云打包

付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios

注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择


腾讯TBS文档阅读器,无需下载X5内核,支持docx、doc、xlsx、xls、pdf、pptx、txt、csv、pdf、epub、chm、rtf等各种文档的预览,自定义水印,防截屏,文本复制粘贴,自定义文档起始页,支持VUE组件集成。

前置条件

1.自定义调试包也是需要申请腾讯浏览服务License,才能调用文档预览,申请链接见步骤4

2.腾讯浏览服务基础版

~~支持1个App客户端免费体验 文件浏览调用量75000次~~ 常见office格式本地浏览 支持dwg、chm等文件格式本地浏览

3.有效期3个月,3月后需在腾讯云购买套餐包才能继续使用,购买链接腾讯浏览服务购买_腾讯浏览服务选购

image.png

插件使用方法

  • 引入插件:

    var tbs = uni.requireNativePlugin("YSCloud-TBSReader")

  1. 原生页面打开文档(android专用)

openAndroidReader(){
// this.filePaths 为本地路径 
//_this.filePaths = plus.io.convertLocalFileSystemURL(res.tempFilePath);
    tbs.openTbsReader(this.filePaths, {
        enableshot: false,  //是否允许该页面被截屏,默认为true,只支持安卓
        enableselect:false, //是否允许用户长按选择文本,默认false,只支持安卓
        pagemodel:false,    //是否开启PPT翻页模式,false,只支持安卓
        startposition:10,   //打开文档后跳转到第几页,默认为1,只支持安卓
        navbar:{
            background:'#468BF7',   //原生导航栏背景色
            text:this.docTitle,     //导航栏标题栏文本
            textcolor:'#FFFFFFFF',  //标题栏文本颜色
            backtext:'返回'           //返回键文本,IOS无效,安卓有效
        },
        watermark:{
            textsize:'22.0',        //水印字体大小
            textcolor:'#FF000000',  //水印字体颜色
            text:'优势智云',            //水印主文本
            subtext:'张三',           //水印副文本
            background:'#FFFFFF00'  //文档背景色 
        }
    }, (ret)=>{
                    //reader事件监听
        //console.log(JSON.stringify(ret));
        switch(ret.code){
            case 7000:
                if(ret.data.typeId == 0){
                    console.log('文档已打开')
                }
                                if(ret.data.typeId == 1){
                    console.log('文档关闭')
                }
                break;
            case 5048:
                                //在翻页过程中,会多次触发
                console.log('文档当前页码:' + ret.data.cur_page + '---' + '文档总页码:' + ret.data.page_count)
                break;
            case 3000:
                console.log('文档被点击')
                break;
            case 3001: 
                //console.log('文档滑动开始,该状态会多次触发')
                break;
            case 3002:
                //console.log('文档滑动结束, 该状态会多次触发')
                break;      
            case 3004:
                //console.log('文档缩放开始,该状态会多次触发')
                break;
            case 3005:
                //console.log('文档缩放结束,该状态会多次触发')
                break;      
        }
    });

},
  1. 关闭文档 (安卓有效,ios无效)

tbs.closeReader();
  1. 滚动到指定页码(安卓专用)

tbs.skip(5)
  1. 用uniapp组件方式集成到nvue页面,页面布局更为灵活,例如下面的代码,可以将uni-icons悬浮于文档组件之上(安卓)

    
    <template>
    <view>
    <!-- <YSCloud-TBSReader ref="reader" 
                :path="filepath" 
                :configures="configures" 
                :style="screenStyle" 
                @event="onReaderEvent">
        </YSCloud-TBSReader> -->
        <YSCloud-TBSReader ref="reader"
                :style="screenStyle" 
                @event="onReaderEvent">
        </YSCloud-TBSReader>
        <cover-view class="controls-title">
                <uni-icons v-if="showLeft" style="margin-right: 30rpx;" color="#0000ff" type="back" size="30" @click="forwardPage"></uni-icons>
                <uni-icons v-if="showRight" style="margin-left: 30rpx;" color="#0000ff" type="forward" size="30" @click="nextPage"></uni-icons>
        </cover-view>
    </view>
    </template>
    <script>
    export default {
    data() {
            return {
                title:'',
                eventMsg:'',
                initMsg:'',
                curPage:1,   //文档当前页码
                showLeft:true,  //是否显示左箭头
                showRight:true, //是否显示右箭头
                screenStyle:'width:750rpx;height:670px',
                pageCount:1,//文档总页码
                filepath:'',//文档绝对路径
                configures:{
                    enableshot: true,//是否允许该页面被截屏,默认为true,只支持安卓
                    enableselect:true,//是否允许用户长按选择文本,默认false,只支持安卓
                    pagemodel:false,//是否开启PPT翻页模式,false,只支持安卓
                    startposition:1,//文档打开时的起始页,默认为1,只支持安卓
                    watermark:{
                        textsize:'22.0',//水印字体大小
                        textcolor:'#FF000000',//水印字体颜色
                        text:'优势智云',//水印主文本
                        subtext:'yszy',//水印副文本
                        background:'#FFFFFF00'//文档背景色   
                    }
                }
            }
    },
    
    //文档加载有两种方式:两种方式只能二选一,
    //第一种方式:直接将参数作为组件属性进行加载显示,如下:
        // <YSCloud-TBSReader ref="reader"
        //    :path="filepath" 
        //    :configures="configures" 
        //    :style="screenStyle" 
        //    @init="onReaderLoaded" 
        //    @event="onReaderEvent">
        // </YSCloud-TBSReader>
    
    //第二种方式:将文档配置数据作为组件的方法的参数加载显示
    //在mounted:方法中调用组件的show方法,如下:
    // 先界面布局
    // <YSCloud-TBSReader ref="reader"
    //  :style="screenStyle" 
    //  @init="onReaderLoaded" 
    //  @event="onReaderEvent">
    //</YSCloud-TBSReader>
    
    //布局完成后,在mounted函数中调用show方法
    // mounted(){
    //  console.log("mounted:");
    //  this.$nextTick(() => {
    //      this.$refs.reader.show(this.filepath, this.configures);
    //  })
    // },
    
    onLoad(option) {
        //动态更新屏幕高度
        const info = uni.getSystemInfoSync();
        this.screenStyle = 'width:750rpx;height:'+ info.windowHeight + 'px'  //设置阅读器组件的高度(全屏显示)
        console.log("screenStyle:" + this.screenStyle)
        this.filepath = option.path;  //接收上一层的文档路径
    },
    mounted(){
        console.log("mounted:");
        this.$nextTick(() => {
            this.$refs.reader.show(this.filepath, this.configures);
        })
    },
    methods: {
        //reader的事件监听
        onReaderEvent:function(ret){
            var that = this;
            console.log("onReaderEvent:" + JSON.stringify(ret.detail));
            switch(ret.detail.action){
                            case 7000:
                                    if(ret.detail.typeId == 0){
                                            console.log('文档已打开')
                                    }
                                    if(ret.detail.typeId == 1){
                                            console.log('文档已关闭')
                                    }
                                    break;
                            case 5048:
                                    console.log('文档当前页码:' + ret.detail.cur_page + '---' + '文档总页码:' + ret.detail.page_count)
                                    this.pageCount = ret.detail.page_count;
                                    this.curPage = ret.detail.cur_page;
                                    this.refreshArrow();
                                    break;
                            case 3000:
                                    //console.log('文档被点击')
                                    break;
                            case 3001:
                                    //console.log('文档滑动开始')
                                    break;
                            case 3002:
                                    //console.log('文档滑动结束')
                                    break;      
                            case 3004:
                                    //console.log('文档缩放开始')
                                    break;
                            case 3005:
                                    //console.log('文档缩放结束')
                                    break;      
            }
        },
    
        //下一页
        nextPage:function(){
            var page = Math.max(Math.min(++this.curPage, this.pageCount), 1);
            this.$refs.reader.skip(page); //跳转到指定页面
            this.refreshArrow();
        },
    
        //上一页
        forwardPage:function(){
            var page = Math.max(Math.min(--this.curPage, this.pageCount), 1);
            this.$refs.reader.skip(page);  //跳转到指定页面
            this.refreshArrow();
        },
        refreshArrow: function(){
            this.showLeft  = this.curPage == 1? false : true;
            this.showRight = this.curPage == this.pageCount ? false : true;
        }
    }
    }
    </script>
    <style>
    .controls-title {
        position: absolute;
        display: flex;
        flex-direction: row;
        justify-content: center;
        width: 750rpx;
        bottom: 10px;
        text-align: center;
        color: #FFFFFF;
    }
    </style>    

提示:如果想实现文档全屏显示,并保留左上角原生悬浮按钮。 请在pages.json将该页面设置标题背景透明

```javascript
{
    "path" : "pages/xxxx/xxxxxx",
    "style" :
    {
        "transparentTitle": "auto",
        "navigationBarTitleText": "预览组件",
        "enablePullDownRefresh": false,
        "app-plus": {
            "titleNView": {
                "type": "transparent"
            }
        }
    }
}       
  1. 原生页面打开文档(ios专用)

 openReader(){

    tbs.openReader(this.filePaths, {
        navbar:{
            background:'#468BF7',   //原生导航栏背景色
            text:this.docTitle,     //导航栏标题栏文本
            textcolor:'#FFFFFFFF',  //标题栏文本颜色
            backtext:'返回'           //返回键文本,IOS无效,安卓有效
        },
        watermark:{
            textsize:'22.0',        //水印字体大小
            textcolor:'#FF000000',  //水印字体颜色
            text:'优势智云',            //水印主文本
            subtext:'张三',           //水印副文本
            background:'#FFFFFF00'  //文档背景色 
        }
    }, (ret)=>{
            console.log(JSON.stringify(ret));
    });

}
  1. 用组件方式集成到nvue页面(只支持IOS)

    组件集成方式只适用于nvue页面

<template>
    <view>
        <YSCloud-TBSReader ref="viewer" @readerLoaded="onReaderLoaded" :style="screenStyle">
        </YSCloud-TBSReader>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                configures: [],
                title:'',
                screenStyle:'width:750rpx;height:670px'
            }
        },
        onLoad() {
            //动态更新屏幕高度
            const info = uni.getSystemInfoSync();
            this.screenStyle = 'width:750rpx;height:'+ info.windowHeight + 'px'
        },
        methods: {
            onReaderLoaded: async function(e) {
                uni.setNavigationBarTitle({
                    title:'文档详情'
                });

                var path = '文档绝对路径'
                var configures = {
                    navbar:{
                        background:'#468BF7',   //原生导航栏背景色
                        text:this.docTitle,     //导航栏标题栏文本
                        textcolor:'#FFFFFFFF',  //标题栏文本颜色
                        backtext:'返回'           //返回键文本,IOS无效,安卓有效
                    },
                    watermark:{
                        textsize:'22.0',        //水印字体大小
                        textcolor:'#FF000000',  //水印字体颜色
                        text:'优势智云',            //水印主文本
                        subtext:'张三',           //水印副文本
                        background:'#FFFFFF00'  //文档背景色 
                    }
                }

                this.$refs.viewer.show(path, configures);
            }
        }
    }
</script>
  1. 申请腾讯浏览服务License,点击申请

    将license保存下来

1681977718124.jpg

  1. 提交云服务器打包

WX20230420-160728@2x.png

  • 注意:打包时务必保证app的包名和申请腾讯license时提交到后台的包名要保持一致

到此插件集成完毕。

  • 功能演示

1688031189762.gif

  1. 常见问题

    一般性问题

什么是公网?

公网指客户端网络环境,属于移动公共互联网环境,区别于专网,局域网或无网络情况的网络环境。

公网版本和私有化版本有什么区别?

公网版本只能在公网环境下使用,SDK 授权打开文档需要网络环境,而私有化版本可以在任意网络下使用,打开文档不受网络限制。

LicenseKey 有什么作用?

LicenseKey 跟客户端包名绑定,用于接入 SDK 后的授权校验等功能。在授权以后,请不要随意更改包名,若需要更换包名,需要重新申请 LicenseKey。

如何查看 LicenseKey?

查看 LicenseKey,需要账户登录以后,到客户端管理页面查看生成的 LicenseKey,请妥善保管 LicenseKey。

SDK 接入问题

SDK 是否支持打开远程服务器文档?

不支持,SDK 只支持打开本地文档,只能传入一个本地文档的路径。服务器文档需要先下载到本地,再调 SDK 打开。

SDK 主要支持什么接入?

SDK 主要只支持 Android 接入,是将文档 API 和文档浏览引擎集成在一起的 SDK 包。

SDK 集成有多大包大小增量?

SDK 集成支持的是32位、64位混合集成,也支持单独64位集成,不同位数包大小不一样,64位数 SDK 在5-10MB区间。个别小众格式单独集成,例如 DWG 格式。详情见 SDK 接入文档。

SDK 集成后首次无法授权成功?

请检查宿主(App)网络环境,是否正常打开联网功能,是否连接了代理,VPN 等网络技术,影响授权请求的正常进行。

Poi 库是否能和 SDK 一起集成?

开发者如果接入了其他的文档解析方案,一般会集成 Poi 库,会跟文档 SDK 产生冲突。

使用这个 SDK 是否还需要下载 X5 内核

文档 SDK 是一个独立的 SDK,不需要下载 x5 内核。

使用这个 SDK 是否可以和 TBS SDK 一起集成?

支持和 TBS SDK 44286 版本(不支持文档 API 接口)以后一起集成。

使用 SDK 是否需要联网

公网版本需要一直联网使用,离线授权版本,可以通过离线的方式授权,用户可以在专网或者无网络下打开文档。

SDK 体验问题

显示文件预览失败

image.png

请检查:

  • filePath 参数传入的文件路径是否正确。
  • 本地文件是否存在。
  • 本地文件是否损坏。
  • 是否有文件读取权限,某些机型上需开启权限设置-特殊权限设置-授予所有文件访问权限。(可查看 logcat 是否有文件权限报错的堆栈)

    SDK 错误码

初始化接口错误码

  • intEngine 接口错误码为方法返回值。
  • initEngineAsync 接口错误码为回调 actionType == ITbsReader.OPEN_FILEREADER_ASYNC_LOAD_READER_ENTRY_CALLBACK 时 args 的值。 image.png

文件打开接口错误码

openFileReader 接口错误码为回调 actionType == ITbsReader.NOTIFY_ERRORCODE 时 args 的值,非0则显示文档预览失败。可按上述“显示文件预览失败”的处理方法进行排查。如未解决,请 联系我们。

App 首次初始化加载组件影响界面卡顿

首次加载组件会进入授权流程,initEngine 接口可在子线程调用,或调用 initEngineAsync 接口。

文件缓存目录如何指定,是否可以删除

tempPath 为文件缓存目录,建议指定在 App 沙盒目录下,无需主动创建目录。 在关闭文件(closeFileReader 接口调用)后可以删除,删除后再次打开文件无法跳转到上次打开的位置。

数据安全问题

SDK 是否会上传文档内容到云端?

文档是本地存储读取,并解析文档渲染展示。除 SDK 初始化会进行授权请求,正常打开文件会上报文件打开次数,无其他敏感数据网络传输,详情请参见 隐私合规文档

扫码添加技术微信支持,备注说明对应的插件名称

咨询电话: 400-008-1668 邮箱:marketing@yszyun.com

隐私、权限声明

1. 本插件需要申请的系统权限列表:

存储,设备信息

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件自身不采集任何数据,插件使用的腾讯浏览服务SDK采集数据,请参考其官方说明:https://rule.tencent.com/rule/preview/b01dde7c-2c5b-487a-9bdd-3275dc716a83

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问