更新记录
1.0.0(2026-10-28)
首个版本:结构化生成 docx(标题/信息表/章节/段落/表格/图片/分页/页脚页码)、A4 纵横与页边距参数化、表格列宽按权重分配与表头跨页重复、PNG/JPEG/GIF 像素尺寸解析与等比缩放、docx 模板 ${字段} 填充(缺值返回 missing 清单)、统一错误码与半成品清理;不引任何三方库,零存储权限。UTS→Kotlin 编译通过(index.kt 1938 行),114 项纯逻辑与 python-docx 往返测试全部通过;真机未执行(测试机未连接)。
平台兼容性
uni-app
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| × | √ | × | × | √ | × | √ | × | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
企业 Word 报告生成(零依赖 docx)
给需要在 App 里出检测报告、巡检单、验收单、合同附件的开发者:用几行调用把业务数据写成标准 .docx,用户拿到就能在 WPS / 手机 Office 里打开、盖章、发客户。
不需要引 POI、docx4j 等三方库,安装包不增加体积;默认写到应用私有目录,不需要任何存储权限。
为什么值得用
现场出单时,客户要的是「一份能盖章的 Word」,不是一张截图,也不是一个只能在本 App 里看的页面。自己拼 OOXML 的坑集中在三个地方:表格列宽算不对、图片比例被拉变形、中文特殊字符没转义导致 Word 报「文档已损坏」。这个插件把这三件事做完了,并且把版式参数化:
- 表格:列宽按权重分配(加总严格等于正文宽度),表头跨页重复、行不跨页,长表格翻页后还能对上列;
- 图片:读 PNG/JPEG/GIF 文件头拿真实像素尺寸,按目标宽度等比缩放,超过正文宽度自动收窄,不会顶出页边距;
- 中文:五个预定义实体转义,并丢弃 XML 1.0 不允许的控制字符——这一条不做,客户数据里混进一个不可见字符,文档就打不开了;
- 模板:客户自己做好的 Word 模板,把
${字段}换成业务数据即可,页眉页脚、样式、图片原样保留。
快速开始
import {
createReport, addHeading, addParagraph, addTable,
addPageBreak, saveReport, abortReport
} from '@/uni_modules/szhzy-docx-report'
const r = createReport({
title: 'LED 驱动电源检测报告',
subtitle: '恒之源检测中心 · 报告编号 SZHZY-2026-1028',
meta: [
['委托单位', '深圳恒之源技术股份有限公司'],
['样品编号', 'S-2026-0417'],
['检测日期', '2026-10-28']
],
footerText: '本报告仅对本次送检样品负责',
footerPage: true
})
if (!r.ok) return console.error(r.code, r.message)
const token = r.token
addHeading(token, { text: '一、检测结果', level: 1 })
addTable(token, {
headers: ['检测项目', '技术要求', '实测值', '判定'],
rows: [
['绝缘电阻', '≥ 2 MΩ', '3.6 MΩ', '合格'],
['接地电阻', '≤ 0.1 Ω', '0.06 Ω', '合格']
],
widths: [18, 34, 24, 16],
aligns: ['left', 'left', 'center', 'center']
})
addHeading(token, { text: '二、结论', level: 1 })
addParagraph(token, { text: '所检项目全部符合 GB 7000.1-2015 要求,判定为合格。', indentCm: 0.74 })
addPageBreak(token)
addParagraph(token, { text: '检测员:陈工 审核:李工', spaceBefore: 12 })
const saved = saveReport(token, { fileName: '检测报告', dateStamp: '20261028' })
if (!saved.ok) abortReport(token)
API
所有接口同步执行,返回统一信封 { ok, code, message, ... },错误用 code 表达,不抛异常给调用方。
| 接口 | 说明 |
|---|---|
createReport(options) |
建文档,返回 token。title / subtitle / meta / landscape / marginCm / fontName / fontSize / footerText / footerPage |
addHeading(token, { text, level }) |
章节标题,level 1–4,带大纲级别(WPS 导航窗格可见) |
addParagraph(token, { text, bold, size, color, align, indentCm, spaceBefore, spaceAfter }) |
正文段落,\n 会变成真正的换行 |
addTable(token, { headers, rows, widths, aligns, headerFill, fontSize }) |
数据表;widths 是相对权重,不是绝对宽度 |
addKeyValue(token, { rows, labelWidthCm, fontSize }) |
两列信息表,报告头部的「委托单位 / 样品编号」区域 |
addImage(token, { path, widthCm, dpi }) |
嵌入型图片;widthCm 缺省用原始尺寸,超宽自动收窄 |
addPageBreak(token) |
分页 |
addSpacer(token, sizePt) |
段后留白 |
saveReport(token, { path, dir, fileName, dateStamp }) |
落盘,返回 path / bytes / blocks / images |
abortReport(token) |
放弃会话,不产生文件 |
readTemplatePlaceholders({ templatePath }) |
列出模板里的 ${字段} |
fillTemplate({ templatePath, outPath, data }) |
模板填充,返回 replaced 与 missing |
模板模式
const keys = readTemplatePlaceholders({ templatePath: '/sdcard/Android/data/<包名>/files/模板.docx' })
const out = fillTemplate({
templatePath: '/sdcard/Android/data/<包名>/files/模板.docx',
outPath: '/sdcard/Android/data/<包名>/files/documents/交货单.docx',
data: { client: '深圳恒之源技术股份有限公司', orderNo: 'PO-2026-0417', amount: '128,600.00' }
})
if (out.code === 'MISSING_FIELD') {
// missing 里是没给值的字段,按业务决定是补数据还是照常出单
}
模板注意两点:
- 数据值必须是字符串,金额、日期请先用
formatFixed这类方法格式化,否则会出现1234.0这种写法; - 占位符要写在同一段文字的同一处。如果客户在 Word 里编辑时把
${字段}拆成了两段(比如中间改过字体),Word 会把它存成多个 run,本插件按纯文本匹配,拆开就匹配不到——让客户重新整段输入一次即可。
购买前必读
- 平台:仅 Android App(uni-app Vue3,
APP-PLUS)。iOS、鸿蒙、小程序、H5 未实现,市场声明里已标不支持。 - 落盘位置:默认
/sdcard/Android/data/<包名>/files/documents,属于应用私有外部目录,卸载 App 时一并删除,不需要存储权限。要写到用户选的目录,请配合文件存取类插件拿到路径或先复制。 - 大表格:单表上限 20 列 / 5000 行,超出请拆表。生成在调用线程执行,几百行是毫秒级;上千行建议放到
setTimeout后再执行,避免卡住页面动画。 - 内容校验:插件只保证「文档结构合法、文字与表格写对」。合同金额、检测结论这类业务判断请在上层做好,插件不做任何业务校验。
- 图片尺寸:按文件头读像素,DPI 缺省 96。手机相册原图常见 72,如果发现图片偏大,显式传
dpi: 72。
验证状态(如实说明)
- UTS → Kotlin 编译:通过(HBuilderX 5.33,
launch app-android --compile true,产物index.kt1938 行,0 error)。 - 纯逻辑回归测试:114 项全部通过,含用同一份 core 逻辑拼出真实
.docx后交 python-docx 读取的往返校验(段落、两张表格的单元格、页脚、图片部件、每个 XML 部件良构)。 - 真机运行:未执行。开发时测试机未连接(
adb devices为空),因此没有真机截图与真机上的落盘验证;市场图为 H5 渲染的真实页面,页面内已标注示例数据与预览环境。 - 未验证项:Android 平台层的 zip 写盘、图片流复制在真机上的表现(逻辑与结构已在 Node 侧验证,但未经设备执行)。
常见错误码
| code | 含义与处理 |
|---|---|
SESSION_NOT_FOUND |
token 无效或已保存,重新 createReport |
SESSION_CLOSED |
已保存/已中止,不能再追加 |
EMPTY_DOCUMENT |
一个字都没写就保存,先加内容 |
ROW_WIDTH_MISMATCH |
某行列数与表头不一致,message 里有行号 |
TOO_MANY_COLUMNS / TOO_MANY_ROWS |
超上限,拆表 |
IMAGE_NOT_FOUND / IMAGE_UNSUPPORTED |
图片路径不可读,或不是 PNG/JPEG/GIF |
TEMPLATE_INVALID |
模板不是有效 docx(缺 word/document.xml) |
MISSING_FIELD |
模板占位符没给值,missing 里是字段名 |
IO_ERROR |
写盘失败,检查空间与文件占用 |

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 13
赞赏 0
下载 12720522
赞赏 1958
赞赏
京公网安备:11010802035340号