@hxa-rn/react-native-html-to-pdf
v1.3.0-beta.1
Published
Convert html strings to PDF documents using React Native
Downloads
69
Readme
react-native-html-to-pdf
本项目基于 react-native-html-to-pdf 开发。如果在使用过程中有任何问题,欢迎在 GitCode 提交 Issue,会及时跟进。
项目介绍
@hxa-rn/react-native-html-to-pdf 是 react-native-html-to-pdf 的鸿蒙(OpenHarmony)适配版本,当前版本 1.3.0-beta.1。
本库为含原生实现的 TurboModule 插件,通过 ArkWeb 渲染 HTML 字符串并调用 createPdf 生成 PDF 文档,支持自定义页面尺寸、文件名与输出目录、Base64 输出、背景色、相对资源加载及页数统计。JS 侧 API 与原库保持一致,业务代码无需修改 import 路径。
集成指南
安装
npm install @hxa-rn/react-native-html-to-pdf依赖要求
| 依赖 | 版本要求 |
|------|----------|
| react | *(peerDependency) |
| react-native | >=0.72(peerDependency) |
| Node.js | >=18 |
业务代码仍使用原库名 react-native-html-to-pdf 导入(harmony.alias),RNOH 自动重定向至 @hxa-rn/react-native-html-to-pdf:
import { generatePDF } from 'react-native-html-to-pdf';Autolinking
本模块支持 Autolinking,安装后由 RNOH 自动链接 HtmlToPdfPackage(C++/ETS 双注册),HAR 位于 harmony/html_to_pdf/,CMake 目标名为 html_to_pdf。
若 Autolinking 未生效,可按以下备选步骤手动注册 Package:
C++ 侧(PackageProvider.cpp):
#include "HtmlToPdfPackage.h"
// ...
std::make_shared<rnoh::HtmlToPdfPackage>(ctx),ETS 侧(RNPackagesFactory.ets):
import HtmlToPdfPackage from '@hxa-rn/react-native-html-to-pdf';
// ...
new HtmlToPdfPackage(ctx),宿主接入要求(必须)
本模块为纯 TurboModule 无 UI,WebviewController 必须绑定 UI 树中的 Web 组件才能调用 loadData / createPdf。宿主必须完成以下三步,否则 convert 返回 WEBVIEW_ERROR,或超时后后续转换被阻塞。完整参考实现见 example/harmony/entry/src/main/ets/ 与 example_auto/harmony/entry/src/main/ets/。
1. EntryAbility:初始化 Web 引擎并启用多渲染进程
顺序不可颠倒:必须先 initializeWebEngine(),再 setRenderProcessMode(MULTIPLE)。
import { webview } from '@kit.ArkWeb';
import { AbilityConstant, Want } from '@kit.AbilityKit';
onCreate(want: Want, launchParam?: AbilityConstant.LaunchParam) {
super.onCreate(want, launchParam);
webview.WebviewController.initializeWebEngine();
webview.WebviewController.setRenderProcessMode(webview.RenderProcessMode.MULTIPLE);
}2. Index.ets:声明隐藏 Web 并注入 Controller
HtmlToPdfConverter 为 HAR 默认入口的具名导出。resetPdfWebController / retirePdfWebController 是宿主方法(不是本库 API),用于超时后重叠挂载新 Web;完整实现见 example/harmony/entry/src/main/ets/pages/Index.ets。
import { webview } from '@kit.ArkWeb';
import { HtmlToPdfConverter } from '@hxa-rn/react-native-html-to-pdf';
Web({ src: 'about:blank', controller: controller })
.width(1)
.height(1)
.visibility(Visibility.Hidden)
.onControllerAttached(() => {
HtmlToPdfConverter.getInstance().bindController(controller, (): void => {
this.resetPdfWebController();
});
})
.onPageEnd((event) => {
HtmlToPdfConverter.getInstance().onPageEnd(event.url, controller);
})
.onRenderExited(() => {
HtmlToPdfConverter.getInstance().onRenderProcessGone(controller);
this.retirePdfWebController(generation);
})3. 超时/取消后:重叠挂载新 Web
ArkWeb 的 createPdf 不可取消;库在 30s 超时后会通过 recoveryHandler 请求宿主重建 Web。宿主需保留旧 Web 仍挂载,同时创建并挂载新 WebviewController(ForEach 多实例),在新 Web 的 onControllerAttached 中再次 bindController,旧 Web 触发 onRenderExited 后再从 UI 树移除。
使用说明
import { generatePDF, type PDFOptions, type PDFResult } from 'react-native-html-to-pdf';
async function createPDF() {
const options: PDFOptions = {
html: '<h1>PDF TEST</h1><p>Hello HarmonyOS</p>',
fileName: 'test',
base64: true,
width: 612,
height: 792,
directory: 'reports',
baseURL: 'https://example.com/',
bgColor: '#ffffff',
shouldPrintBackgrounds: true,
};
try {
const result: PDFResult = await generatePDF(options);
console.log(result.filePath);
console.log(result.numberOfPages);
console.log(result.base64);
} catch (e) {
const err = e as { code?: string; message?: string };
console.log(err.code, err.message);
}
}错误处理:generatePDF 失败时 reject 的结构化错误包含 code 与 message 字段,常见错误码见接口文档。
接口文档
generatePDF(options: PDFOptions): Promise<PDFResult>
将 HTML 字符串渲染为 PDF 文件并写入应用沙箱,返回文件路径及可选的 Base64 编码与页数。
底层 TurboModule 方法名为 HtmlToPdf.convert,JS 层通过 generatePDF 封装并统一错误格式。
PDFOptions
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| html | string | 是 | HTML 字符串;空字符串或非字符串类型返回 INVALID_HTML |
| fileName | string | 否 | 输出文件名(不含 .pdf 后缀);缺省自动生成 PDF_<UUID>;非法字符返回 INVALID_FILENAME |
| width | number | 否 | 页面宽度(磅);缺省 612 |
| height | number | 否 | 页面高度(磅);缺省 792 |
| base64 | boolean | 否 | 为 true 时在结果中返回 PDF 的 Base64 编码 |
| padding | number | 否 | 页面边距(iOS Only,鸿蒙端不生效) |
| paddingTop | number | 否 | 上边距(iOS Only,鸿蒙端不生效) |
| paddingBottom | number | 否 | 下边距(iOS Only,鸿蒙端不生效) |
| paddingLeft | number | 否 | 左边距(iOS Only,鸿蒙端不生效) |
| paddingRight | number | 否 | 右边距(iOS Only,鸿蒙端不生效) |
| bgColor | string | 否 | 十六进制背景色;通过注入 HTML body 背景样式实现 |
| directory | string | 否 | 相对应用 filesDir 的子目录;缺省使用 cacheDir;目录创建失败返回 FOLDER_ERROR |
| baseURL | string | 否 | HTML 相对资源(图片/样式)的加载基准地址 |
| shouldPrintBackgrounds | boolean | 否 | 是否打印 CSS 背景;透传至 PdfConfiguration.shouldPrintBackground |
PDFResult
| 字段 | 类型 | 说明 |
|------|------|------|
| filePath | string | 生成的 PDF 文件绝对路径 |
| base64 | string | 可选;base64: true 时返回 PDF 的 Base64 编码 |
| numberOfPages | number | 可选;PDF 页数;依赖 PDF Kit 解析,失败时不返回该字段 |
错误码
| 错误码 | 说明 |
|--------|------|
| INVALID_HTML | HTML 为空、未传或非字符串 |
| INVALID_FILENAME | 文件名含非法路径字符 |
| FOLDER_ERROR | 输出目录创建失败 |
| CONVERSION_IN_PROGRESS | 上一次转换尚未完成 |
| PDF_CONVERSION_TIMEOUT | 单次转换超过 30 秒 |
| WEBVIEW_ERROR | Web 组件未绑定或 loadData 失败 |
| PDF_WRITE_ERROR | PDF 文件写入失败 |
| PDF_GENERATION_ERROR | 其他 PDF 生成异常 |
快速验证(运行 Example)
前置条件
| 依赖 | 版本要求 |
|------|----------|
| Node.js | >= 18(运行 Example 建议 >= 20,见 example/package.json) |
| DevEco Studio | 5.0+ / 6.0+ |
| HarmonyOS SDK | API 13+(example/harmony 的 compatibleSdkVersion 为 5.0.1(13)) |
运行步骤
1. 克隆仓库
git clone https://gitcode.com/hxa-rn/react-native-html-to-pdf.git
cd react-native-html-to-pdf
git checkout br_rnoh0.722. 进入 example 目录,安装依赖
cd example
npm install --legacy-peer-depsExample 已改为从 npm 公仓安装 @hxa-rn/[email protected],不再使用本地 file:../xxx.tgz,运行 Example 不必再执行 npm pack。
3. 生成 JS Bundle
npm run dev产物:harmony/entry/src/main/resources/rawfile/bundle.harmony.js
4. 安装鸿蒙依赖
cd harmony
ohpm install5. 用 DevEco Studio 打开鸿蒙工程
- 打开 DevEco Studio
- 选择
example/harmony目录 - 首次构建请在 File → Project Structure → Signing Configs 勾选 Automatically generate signature,Apply 后 Sync
- 等待 Sync 完成
6. 编译并运行 HAP
在 DevEco Studio 中点击运行按钮,将 HAP 安装到设备/模拟器。
注意:Example 已预置 Autolinking Package 注册、Metro alias 与 HAR 依赖,无需手动 Link。编 HAP 前必须先执行
npm run dev。createPdf为 API 14+ 能力,请在 HarmonyOS 5.1+(API 14 及以上)真机或模拟器上验证。
约束与限制
兼容性
| 项目 | 要求 |
|------|------|
| React Native / RNOH | RN >=0.72;框架基线 RNOH 0.72 |
| Node.js | >=18(运行 Example 建议 >=20) |
| HarmonyOS SDK | 编译 5.0.1(13)(example/harmony 的 compatibleSdkVersion);运行期 createPdf 需 API 14+(HarmonyOS 5.1+) |
| 运行期最低系统 | API 14(HarmonyOS 5.1+):createPdf 为 API 14+ 能力,API 13 及以下设备运行期抛能力不支持错误 |
权限
插件 HAR(harmony/html_to_pdf/src/main/module.json5)声明:
| 权限 | 用途 |
|------|------|
| ohos.permission.INTERNET | ArkWeb 通过 baseURL 加载网络相对资源 |
平台差异与已知限制
padding/paddingTop/paddingBottom/paddingLeft/paddingRight为 iOS Only 参数,鸿蒙端不生效(与 Android 行为一致)。numberOfPages依赖 PDF Kit(@kit.PDFKit),官方仅支持中国大陆(港澳台除外);解析失败时该字段不返回,不影响 PDF 生成主流程。bgColor通过注入 HTML body 背景样式 +shouldPrintBackground=true实现;若 HTML 自带 body 背景样式可能互相覆盖。width/height单位为磅,鸿蒙端按 1 磅 = 1/72 英寸换算为PdfConfiguration英寸单位;非法或缺省尺寸按默认 612×792 磅处理。- 单次转换 30s 超时保护;转换进行中再次调用返回
CONVERSION_IN_PROGRESS。 createPdf不可取消;超时后须宿主配合 Web 重建(见集成指南第 3 步)。base64: true时整文件读入编码,超大文件有内存峰值风险。
开源license
本项目基于 MIT 协议,详见 LICENSE 文件。
问题反馈渠道
- GitCode 仓库:https://gitcode.com/hxa-rn/react-native-html-to-pdf
- 提交 Issue:https://gitcode.com/hxa-rn/react-native-html-to-pdf/issues
