• ofdkit-harmony 0.2.0 发布:鸿蒙原生 OFD 阅读库,已上架 ohpm


    软件简介

    ofdkit-harmony 是一个面向 HarmonyOS NEXT 的原生 OFD 阅读 / 渲染库,完全用 ArkTS 实现,不依赖 WebView、JNI 或 native 桥接,遵循国家标准 GB/T 33190-2016。适用于电子发票、电子公文、电子合同等典型 OFD 场景。

    • 项目地址https://gitee.com/notcoder/ofdkit-harmony
    • 开源协议:Apache License 2.0
    • ohpm 包名ofdkit-harmony
    • 当前版本:0.2.0
    • 运行环境:HarmonyOS NEXT(暂不支持 OpenHarmony,库内使用 @kit.* Kit 命名空间 API)

    主要功能

    • 多页 OFD 文档打开(电子发票 / 电子公文 / 电子合同)
    • 模板页 + 注释 + 路径 / 图片 / 文字对象完整解析
    • 双指捏合缩放 / 单指拖动 / 双击复位
    • 侧滑切页 + 多页连续滚动 + 缩略图条
    • 跨页全文搜索 + 命中高亮 + 上下跳转
    • 长按选中文字 → 复制到剪贴板
    • 嵌入字体注册 + 全局兜底字体 API

    一行安装

    ohpm install ofdkit-harmony
    

    演示

    demo

    快速接入

    import {
      OFDParser,
      OFDPageView,
      installDefaultExtensions
    } from 'ofdkit-harmony';
    
    // 应用启动时调用一次
    installDefaultExtensions();
    
    // 解析
    const parser = new OFDParser({ workDir: '/path/to/cache' });
    const doc = await parser.parse('/path/to/file.ofd');
    
    // 渲染
    @Component
    struct Reader {
      @State doc: OFDDocument = doc;
      @State pageIndex: number = 0;
    
      build() {
        OFDPageView({ page: this.doc.pages[this.pageIndex] })
      }
    }
    

    OFDPageView 内部自动处理字体注册、图片解码、Canvas 绘制和手势。

    架构

    四层:UI 组件 → Renderer → Parser → 扩展点。三类扩展点向上开放(ObjectParserExt / ObjectRendererExt / DocumentExtension),验签 / 转换 / 表单等能力都能用同一套机制接入,不必侵入核心库。

    几个值得说的实现细节

    1. DeltaX/DeltaY 定位的几个坑

    OFD 文字对象用 DeltaX 数组定位每个字符。规范里有一个 g N v 重复格式(如 3.5 g 5 4.2 1.8 表示 [3.5, 4.2×5, 1.8]),实际样本里还经常出现 DeltaX 数组比字符串短(要重复最后一个值兜底)、负 DeltaX(密码区多行布局)等情况。早期把「DeltaX 太小就用字符自然宽度兜底」的逻辑加进去,结果把负值也覆盖了,密码区直接错乱——后来改成负值跳过兜底。

    2. 字体处理:嵌入 ttf + 全局兜底 API

    嵌入字体直接用 font.registerFont 注册到 ArkUI 字体表,Canvas 直接用字体名。但大多数电子发票只声明 FontName="宋体" 不嵌入文件——HarmonyOS Sans 是无衬线,跟纸质发票的衬线宋体差别明显。所以加了:

    OFDRenderer.setFallbackFontFamily('OFD-Fallback');
    

    调用方自己注册字体到系统表(避免授权风险),然后告诉 Renderer 用这个 family 兜底,视觉立刻接近纸质发票。

    3. ZOrder 与模板页

    模板页 ZOrder 有 Background / Foreground 两种。电子发票的「红章框」常常是 Foreground 模板,必须最后绘制,否则会被发票数据盖住。渲染顺序:模板 Background → 主页对象 → 模板 Foreground → 注释 → 签章。

    4. AbbreviatedData 路径的 A 命令

    OFD 路径 A 命令参数是 SVG 风格的 rx ry rotate largeArc sweep x y,但 Canvas 没有 SVG 圆弧 API,要换算成 ellipse(cx, cy, ...)。endpoint-to-center 推导那一段代码挺繁琐,仓库里 parsePath.ts 有完整实现。

    5. OFD 套 OFD:矢量印章的递归解析

    最有意思的一个细节——电子发票的红章本身就是一个嵌入的 OFD 文件(picture.type='OFD')。完整结构:

    主 OFD 文档
    └── StampAnnot
        └── SES_Signature
            └── picture
                ├── type='png'    → 光栅印章,PixelMap 直绘
                └── type='OFD'    → 矢量印章,递归解析渲染
    

    递归渲染时字体命名要做命名空间隔离(嵌入文档的字体注册加 stamp_${stampId}_ 前缀),否则跟主文档同名字体(都叫 Font_F1)会互相覆盖。

    实际踩过的小坑

    • LongPressGesture 被 PanGesture 抢占:长按选字 500ms 触发不了 → 用 priorityGesture 独立挂 LongPress,比子组件 / 兄弟手势先识别。
    • 模板页常常不带 PhysicalBox:规范说应有,实际样本里大多没有 → 模板页 Area 改为可选,缺省继承主页。
    • OFD 包路径大小写不一致:XML 写 Doc_0/,实际文件名是 doc_0/ → 加 resolveCaseInsensitive 兜底。
    • 部分电子发票对象不带 ID:早期当必需字段直接报错 → 改可选,用对象顺序号兜底。

    API 概览

    • OFDParser — 解析入口
    • OFDPageView — 单页渲染组件
    • OFDDocumentScroll — 多页连续滚动视图
    • OFDThumbnailStrip — 缩略图条
    • SearchController + OFDSearchBar — 跨页全文搜索
    • OFDRenderer.setFallbackFontFamily — 全局兜底字体

    完整 API 与示例见仓库 README。

    后续路线

    • CMYK / Pattern / Gradient 色彩空间补全
    • 表单填充
    • 国密 SM2/SM3 签章验签(已在企业版闭源分支验证,开源版规划中)

    欢迎在 Gitee 仓库提 Issue 反馈实际样本踩坑,任何兼容性问题都会跟进。

  • 相关阅读:
    【配准和融合相互作用,交互】
    Java排序算法之基数排序
    WebRTC Native M96 基础Base模块介绍之网络相关的封装
    连接Mumu模拟器使用ADB
    【二叉树-中等】1104. 二叉树寻路
    家庭用户无线上网案例(AC通过三层口对AP进行管理)
    PTA 7-49 数油桶
    华为OD机试真题 Java 实现【简易内存池】【2023 B卷 200分 考生抽中题】
    互联网Java工程师面试题·MyBatis 篇·第二弹
    模型训练前后显卡占用对比、多卡训练GPU占用分析【一文读懂】
  • 原文地址:https://www.cnblogs.com/each404/p/20149233