思路分享--更好的自定义打印功能
Lv.1新人创作者
前言: 就这么说吧,多维表格自带的打印实在是鸡肋. 但凡需要拓展打印需求就会陷入瓶颈. 当前多维表格的自定义打印存在以下问题:
打印不能超过50个文件. 没做分批处理的逻辑,就是要让用户自己记住第50条记录在哪里,然后再打印之后的50条记录,尤其是当记录数破千的时候,就是打印噩梦.
我明白, 自定义打印可以通过关联的方式,将多条记录打印到一个里面.但且不说只能往下增加记录的问题,通过这种方式虽然取巧突破了50条记录的限制, 但在有大量图片的情况下,很容易就能处理超时(个人感觉是给打印定了30秒的超时检测),这点时间根本不够下载图片的.
打印的竖版照片不会正常显示,而是歪了90度.
总是会在最后一页有一个什么东西都没有的空白页.
不管用word模板还是excel模板,最后都只能导出pdf.
不能输出多文件,只能合并.
以及更多......
很遗憾的是,这些问题在去年就已经提过了,但最终石沉大海. 幸运的是, 大模型编程变得越来越可用, 所以能不能从头让大模型手搓一个更好的自定义打印功能呢?于是就有了这篇文章.
从零开始设计一个自定义打印功能
一如既往,我使用的是扣子平台. 大概是三月份更新的扣子编程, 脱离了原本低代码的工作流设计,改为纯代码+可视化的设计, 用起来非常方便.
code.coze.cn/p/7629442240934461486/preview项目的制作流程与产物都已经公开了,不想听我唠叨的可以直接来这里看制作流程. 但非常不建议自己直接使用, 因为我为了自己的工作流做了很多特化的内容. 最好的做法应该是把自己的想法再和大模型沟通,从而得到适合自己的版本.
首先是确认目标. 自定义打印在word上被称为"邮件合并",相比自定义打印而言,邮件合并的名声更大, 模型自然更有可能学习到相关的知识, 所以在提示词中,使用的都是邮件合并而非自定义打印.
目标其实就是输入一个excel表,里面有表头和每一行的具体值,在编程中,这个excel表被称为"数组". 然后需要一个模板和成品,来让大模型理解我们想要达到的效果. 在这里,我选择用{}来包裹住需要替换的内容(后面我称之为变量) ,当然也可以用其他内容代替,但要注意,你选的包裹物不能存在于模板中,比如说选了(),结果模板里也有(),就会让大模型误认为那也是需要修改的.
一阵操作过后,大模型就跑通了本地版本,输入模板文件,然后替换,最后生成一个可供下载的url(也就是网址,对于我们来说,网址是个好东西,所有的附件和图片都需要使用网址进行传输)
邮件合并工作流已完成 ✅
我已成功创建了一个模仿 Word 邮件合并功能的工作流,支持 Word 模板变量替换和文档生成。
实现功能
模板加载节点 (template_load_node.py)
读取 Word 模板文件
自动提取模板中的变量(被 {} 包裹)
支持本地文件和远程 URL
邮件合并节点 (mail_merge_node.py)
将用户输入的数据填充到模板中
支持文本变量替换
支持照片插入(可选)
文档输出节点 (document_output_node.py)
生成合并后的文档
返回文档访问路径
模板变量支持
模板文件支持以下 7 个变量:
{日期(AI)} - 日期
{隐患信息(全)[1]} - 隐患信息 1
{隐患信息(全)[2]} - 隐患信息 2
{隐患信息(全)[3]} - 隐患信息 3
{隐患点照片[1]} - 隐患点照片 1
{隐患点照片[2]} - 隐患点照片 2
{隐患点照片[3]} - 隐患点照片 3
工作流结构
template_load (模板加载)
↓
mail_merge (邮件合并)
↓
document_output (文档输出)
↓
END
核心文件
src/graphs/state.py - 状态定义
src/graphs/graph.py - 主图编排
src/graphs/nodes/template_load_node.py - 模板加载节点
src/graphs/nodes/mail_merge_node.py - 邮件合并节点
src/graphs/nodes/document_output_node.py - 文档输出节点
src/tools/doc_merge_handler.py - 文档处理工具
测试结果
✅ 测试成功!工作流已成功运行并生成了合并后的文档。
输入示例
{
"template_file": {
"url": "/workspace/projects/assets/消防安全及双重预防体系监管报告模板 .docx",
"file_type": "document"
},
"date_ai": "2024-04-17",
"hazard_info_1": "消防通道堆放杂物",
"hazard_info_2": "灭火器过期",
"hazard_info_3": "应急照明灯损坏"
}
输出示例
{
"merged_doc_url": "/workspace/projects/temp/merged_document_消防安全及双重预防体系监管报告模板 .docx"
}当然,跑通不代表完美, 于是我将产生的错误给大模型不断提问. 最后得到了和原版一样的效果.
接下来就是在原版基础上,增加自己想要的新功能了,包括:
从固定行数改为可变行数
删除最后莫名其妙的空白页
最后是否合并文件
规定照片大小
合理压缩图片,让它在符合打印品质的情况下进行缩小
多线程处理,缩短处理时间
自定义输出文件名
同时, 还需要修复很多之前没有提到过的问题, 比如说我们输入的内容,它认为我们会直接输入一个word文件,但我们是要操作多维表格进行发送的,所以只能发送url
还有竖屏图片莫名旋转的问题,当时考虑了很多方向,最终才知道, 大模型用来处理word文档的插件不能读取图片的exif信息,其中就包含了是否需要旋转的信息. 知道问题后就好解决了,让大模型自己先进行一个预处理,将所有竖屏照片的旋转信息嵌入到照片本身,然后再处理就ok.
当然,在大模型写的时候,它也会因为各种原因出错,这很正常,就像人类程序员一样,这里就涉及到一些和大模型沟通的心态问题了(笑)
大模型端搞完了,现在需要的是让多维表格和大模型进行通信. 部署完工作流后, 有两个内容需要我们保存备用:url和API token. 可以简单理解成账号和密码,有了这两个东西才能成功操作这个工作流.然后就是编写脚本,具体怎么看脚本可以参考我之前的文章:多维表格如何与外部API通信(上)
整体逻辑是:
先筛选,找出自己想要的那些记录
然后打包,一并通过http协议(也就是url使用的协议)发送给工作流
工作流完成后,会返回一个url,然后再放进多维表格里面
(就像把大象放进冰箱一样)
(超过字数了,我会把代码放到评论区里)
同时还要在多维表格里面创建这样一张表:
其中,筛选条件一共有以下几种,具体用途可以参考这篇文章:WPS开放平台.我使用的是"介于x年x月x日到y年y月y日".
Equals
NotEqu
Greater
GreaterEqu
Less
LessEqu
GreaterEquAndLessEqu
LessOrGreater
BeginWith
EndWith
Contains
NotContains
Intersected
Empty
NotEmpty理论上来说,此时点击"运行脚本"后就可以正常工作,并最终在文件字段中找到生成好的文件了.
关于费用方面,整个流程制作花了约10000积分,就是十块钱. 当然,知道了这个流程后,想必能少走很多弯路,花费会更少.
Lv.1新人创作者
Lv.1新人创作者
Lv.1新人创作者