大道至简,新一代企业应用无栈开发

平台之上,一种语言,可视化、脚本化、全端一体化开发

文件查看器

提供插件机制,支持各种格式的文件在线查看

docutils document without title

不同的文件,有不同的查看器。有些文件可以直接查看,有些需要转换。

1   支持的文档查看器

  • 文档查看器

  • 图片查看器

    如同图片小于 300K,会采用原始图片查看,否则大图片会采用缩略图 "image/x-thumbnail-png" 查看。

  • 视频播放器

  • 音频播放器

  • 压缩包查看器

    1. 快速查看压缩包包含的文件
    2. 直接下载压缩包中的文件
    3. 对压缩包中的文件再次查看
    4. 对压缩包中的压缩包,无穷层级查看
  • svg图形查看器

  • flash/swf查看器

  • 邮件查看器

  • 页面查看器: 主要用于html/md/rst等格式的文件查看

  • 3D文件查看器

    支持:

    • 3ds: Autodesk 3D Studio(支持纹理)
    • obj, mtl:Wavefront的3D图形和材质文件 (支持纹理)
    • stl: 最早用于3d打印 (支持文本和二进制格式)

    将来支持:

    • .stp:STEP
    • .sldprt, .sldasm: SolidWorks 98 - 2017
    • prt, .asm: Pro/E / Creo Pro/E 16 - Creo 4.0
    • .par, .asm, .psm: Solid Edige V18 - ST9
    • .ipt, .iam: Inventor V11 - 2017
    • .model, .exp: CATIA V4
    • .CATPart, .CATProduct, .CGR: CATIA V5
    • .CATPart, .CATProduct, .CGR, .3DXML: 3DEXPERIENCE/CATIA V6
  • 文本查看器

2   查看器统一入口

不管当前是什么文件,可以统一使用如下脚本调用合适的查看器:

root.call_script('zopen.viewers:index',
            context=file_obj,
            request=request,
            view=view,
            id="test-doc",
            klass="",
            viewer="", # 强制使用那个查看器
            expire=None,
            features=[],
            permissions=['copy', 'print', 'download', 'pdf'],
            pages=[],
            watermark=dict(text="", color="", size="",),
            )

其中:

  • watermark: 水印信息:
    • font: 字体,默认宋体
    • text:水印文字
    • color: 水印的颜色
    • size:水印字体大小
  • permissions: 查看的权限:
    • copy:是否允许复制文字
    • print:是否允许打印
  • features: 要求查看器提供何种特性,比如:
    • watermark: 水印
    • pages: 限制查看页面
    • print:打印
    • copy:复制文字
    • select: 选择文字
    • position:点选
    • rect:框选
  • expire: 预览链接什么时候失效(时间戳)
  • width: 查看器宽度
  • height: 查看器高度
  • pages: 允许查看哪些页面,默认查看所有页面

这个入口:

  • 根据查看器注册信息,自动和当前文档匹配的查看器
  • 根据查看器按钮插件注册信息,自动加载匹配的按钮

3   编写查看器

查看器插件是一个约定命名以 viewer_ 开头的python脚本,用于提供文件展示的UI组件,提供如下功能:

  • 渲染指定格式的文件内容
  • 背景水印渲染
  • 权限控制的功能:复制文字、打印
  • 提供工具条:
    • 控制文档展示,比如启动、翻页、暂停、放大、缩小
    • 可插入用户自定义按钮,包括图标、文字、action地址
  • 触发一组事件,用于外部捕获
  • 提供一组方法,用于外部控制

3.1   查看器脚本接口形式

查看器脚本的基本接口为:

doc_viewer = root.call_script('xxx.xxx:viewer_xxx',
                context,
                request,
                view,
                file_url,
                mime,
                source_mime,
                filesize,
                addon_urls, # {addon_mime1:url1, addon_mime2:url2}
                request,
                id="",
                buttons=[],
                klass="",
                height=None,
                file
                watermark={},
                permissions=['copy', 'print'],
                pages=[],
                **kw)

这个会返回查看器对象,如果查看器不支持查看该文件,可返回None,查看器入口会尝试使用下一个注册查看器。

其中:

  • context: 这个是上下文,通常是原始文件对象,但是也可能不是。因此这个context对象不建议在查看器中使用

  • reqeust:原始请求对象,不建议使用

  • view:前端view对象

  • file_url:预览文件的下载地址

  • addon_urls:查看器需要的附加mime的文件下载地址(会固定包含原始文件的下载地址)。具体mime的定义,参见查看器脚本描述json,形式:

    { mime1:url1, mime2:url2}
    
  • id: 查看器组件的id

  • klass: 样式class

  • mime: 待预览文件的mime,可以根据这个文件名反查文件后缀:

    import mimetypes
    print mimetypes.guess_extension('applicaiton/x-ext-odf')
    
  • source_mime: 查看器的原始文件的mime,如果source_mime和mime相同,表示直接预览原始文件

  • filesize: 原始文件的大小。如果原始文件太大,可能选择预览转换后的压缩文件。

  • file_key: 标识这个文件内容的key (查看器用这个id做缓存加速文件)

  • buttons:附加按钮信息:

    [
       {'id':button_id, 'icon':icon_name, 'title':button_title, 'url':actoin_url}
    ]
    
  • permissions:允许的权限, copy/print/download/pdf,详见 zopen.viewers:index 接口

  • pages:允许查看的页面

  • height:查看器组件的高度,如果为None,默认会使用屏幕最大高度

  • watermark:水印信息,详见 zopen.viewers:index 接口

3.2   查看器脚本的描述json

在查看器脚本的描述信息里面,用json来记录这些信息.

比如 flash查看器脚本 zopen.viewers:viewer_flash 的附加信息(annotation):

{
    'mimes':['application/x-paged-flash-x'], # 可查看的文件mime
    'features': ['pages', 'watermark'], # 支持的特性
    'addons':['application/x-json'], # 文件查看,附加需要mime转换,比如json
    'browser':['flash'] # 浏览器的要求支持flash
}

其中:

  • mimes: 只能用于查看某些特定的文件mime
  • features: 支持的特性,详见 zopen.viewers:index
  • addons: 附加转换文件的mime类型,根据这个生成addons_ulr
  • browser: 适用于满足要求的浏览器,如果发现浏览器不支持,查看器会跳过这个查看器尝试下一个
    • h5:要求支持h5
    • flash:要求支持flash
    • pc:要求pc
    • mobile:要支持手机
    • tablet:要求平板

3.3   可选实现的方法

3.3.1   打印 print

view.select('#test-doc').call('print')

3.3.2   放大 zoom_in

view.select('#test-doc').call('zoom_in')

3.3.3   缩小 zoom_out

view.select('#test-doc').call('zoom_out')

3.3.4   全屏 full_screen

view.select('#test-doc').call('full_screen')

3.3.5   加载页面 load_page

view.select('#test-doc').call('load_page', 4)

3.3.6   跳转页面 scroll_to

view.select('#test-doc').call('scroll_to', 1)

3.3.7   切换点选模式 click_mode

view.select('#test-doc').call('click_mode', 'position')

包括如下模式:

  • position: 点击位置
  • rect: 拉矩形框
  • select: 选择文字

3.3.8   启动播放 play

view.select('my_viewer').call('play')

3.3.9   跳转到某个位置 goto

view.select('my_viewer').call('goto', 110)

3.3.10   定制播放 stop

view.select('my_viewer').call('stop')

3.3.11   请求进度 report_progress

view.select('my_viewer').call('report_progress')

3.4   可选抛出的事件

3.4.1   定位事件 position

view.select('#test-doc').on('position', context, request, 'zopen.tests:test')

3.4.2   拉框事件 rect

view.select('#test-doc').on('rect', context, request, 'zopen.tests:test')

3.4.3   选择事件 select

view.select('#test-doc').on('select', context, request, 'zopen.tests:test')

3.4.4   进度报告

view.select('my_viewer').on('progress', context, request, '...')

3.5   注册查看器

访问 zopen.views:setup 可以对站点各种查看器进行配置

在站点根 root.settings['viewers'] 中记录了站点默认注册的查看器:

{
'office': ['zopen.viewers:viewer_h5', 'zopen.viewers:viewer_flash'],
'text': ['zopen.viewers:viewer_text'], # 文本
'image': ['zopen.viewers:viewer_image'],     # 图片
'draw': ['zopen.viewers:viewer_h5', 'zopen.viewers:viewer_flash'],     # 绘图
'application/dwg': ['zopen.viewers:viewer_h5', 'zopen.viewers:viewer_flash'],    # 2d图纸
'application/dxf': ['zopen.viewers:viewer_h5', 'zopen.viewers:viewer_flash'],    # 2d图纸
'mail': ['zopen.viewers:viewer_mail'], # 邮件
'zip': ['zopen.viewers:viewer_zip'], # 压缩包
'video': ['zopen.viewers:viewer_video'], # 视频
'audio': ['zopen.viewers:viewer_audeo'], # 音频
}

上面是设置大的mime分类,可可以设置某个子类,比如office中的exce:

'excel': ['zopen.viewers:viewer_h5', 'zopen.viewers:viewer_flash'],

或者设置某个具体的mime:

'text/x-paged-html': ['zopen.viewers:viewer_h5'],
'application/x-showsw-x': ['zopen.viewers:viewer_flash'],
'text/x-page': ['zopen.pages:viewer_page'],
'text/mp4':['zopen.viewer:viewer_video'],

比如新增使用pdfjs来查看文档:

new_viewer = 'zopen.viewers:viewer_pdfjs' # 新的查看器插件脚本
viewers = root.settings.setdefault('viewers', []).setdefault('office', [])
if new_viewer not in viewers:
    viewers.append(new_viewer)

4   编写查看器按钮 viewer_buttons

查看器通过插件按钮,扩展功能。

4.1   编写查看器按钮脚本

点击按钮,将调用这个脚本,传递如下参数:

  • context: 当前的查看的文件
  • request:当前请求信息
  • viewer_id:查看器id
  • features:当前查看器支持的特性

插件脚本和按钮的关系:

  • 按钮图标:使用脚本的图标
  • 按钮显示条件:对当前文件有脚本访问权限
  • 按钮名称:脚本的标题

4.2   查看器按钮脚本的附加信息

按钮展示的条件,这个记录在按钮脚本的附加信息中:

{'browser':['pc'],
 'features': ['position'],
}

其中:

  • browser: browser要求是pc端
  • features:对查看器的特性要求(这个暂未使用)

4.3   注册查看器按钮脚本

插件按钮对应一个脚本,存放在如下位置:

root.settings['viewer_buttons']

具体的值为:

{mime1:[script1, script2],
 mime2:[...]
 }

例子:

{
    'application/xxxx-docx': ['zopen.signature:add_sign'],  # 签章
    'office':['zopen.views:file_info'], # 查看文件信息
}

上面:

  • mime:原始文件的mime类型,
  • script:插件脚本的完整名字