怎样自动把报表插入到 word 文档中

简介: 自动把报表插入到 word 文档中

在很多业务场景中需要在 word 文档中嵌入报表。比如下图这个报告:
1

这是一个某大学年度毕业生就业报告,其中表格和统计图的数据来自数据库,如果通过报表工具,制作这样的表格和统计图是轻而易举的事情,但如果要把这些报表和统计图做到 word 报告里就麻烦很多。以往有两个办法:一个是每次做好报表和统计图之后,导出为 word,再手工复制粘贴到 word 报告中;第二个是把整个报告都做成一个报表模板,然后再一起导出为 word。 方法一,纯手工操作效率低;方法二,报表工具排版能力有限,生成的 word 版面效果不够完美。
那么,还有什么好办法呢?
通常这类报告都有规定的模板样式,只是要定期替换里面的个别信息,比如上图所示的文档编号,报告时间,标题里的年度,图片,每个章节下的报表和统计图,这些信息是动态变化的,而其他文字描述部分以及整体样式都是固定不变的。所以,如果能把报表嵌入 word 文档做成流水线式的自动化过程,那就是一件两全其美,事半功倍的事情。
润乾报表就提供了把报表嵌入 word 的功能,实现步骤如下:
1、制作 word 模板,将需要插入内容的位置设置好书签
2

比如我们开篇看到的大学毕业生就业报告,我们可以先做成如上图所示的 word 模板,图示绿色线框位置就是需要定期更新的部分,预先在这些位置插入书签(比如书签名为:编号,时间,logo,年度,报表,统计图),以此标记要插入到 word 的内容对应插入到什么位置。
2、制作报表,这一步就不详述了。
3、调用润乾报表的 raqsoft.report.view.oxml.word.DocxChanger 里的方法,将图片,文本,报表等内容插入到指定书签位置,生成新的 word 报告。
eg:
//设置报表授权文件
File flic = new File("c:/tmp/report5.lic");
FileInputStream lis = new FileInputStream(flic);
Sequence.readLicense( Sequence.P_RPT, lis);

File f = new File("E:/test.docx"); //模板文件
File of = new File("D:/out.docx"); //输出文件
… …
FileOutputStream fos = new FileOutputStream(of);
DocxChanger dc = new DocxChanger(f, fos); //实例化DocxChanger

//在书签“编号”,“时间”,“年度”处插入文字
dc.insertText("编号", "12345678");
dc.insertText("时间", "20170730");
dc.insertText("年度", "2017");

//在书签“logo”处插入图片文件
File f1 = new File("d:/logo.png");
dc.insertImage("logo", f1);

//在书签“报表”,“统计图”处插入报表和统计图
File f2 = new File("d:/毕业去向.rpx");
FileInputStream fis = new FileInputStream(f2);
IReport report = ReportUtils.read(fis);
fis.close();
Context context = new Context();
… …
Engine engine = new Engine((ReportDefine) report, context);
report = engine.calc();
dc.insertReport("报表", report);

File f3 = new File("d:/留学.rpx");
FileInputStream fis2 = new FileInputStream(f3);
IReport report2 = ReportUtils.read(fis2);
fis2.close();
Context context2 = new Context();
… …
Engine engine2 = new Engine((ReportDefine) report2, context2);
report2 = engine2.calc();
dc.insertReport("统计图", report2);

//执行所有修改动作,然后关闭输出文件流
dc.execute();
fos.close();
//设置报表授权文件
File flic = new File("c:/tmp/report5.lic");
FileInputStream lis = new FileInputStream(flic);
Sequence.readLicense( Sequence.P_RPT, lis);

File f = new File("E:/test.docx"); //模板文件
File of = new File("D:/out.docx"); //输出文件
… …
FileOutputStream fos = new FileOutputStream(of);
DocxChanger dc = new DocxChanger(f, fos); //实例化DocxChanger

//在书签“编号”,“时间”,“年度”处插入文字
dc.insertText("编号", "12345678");
dc.insertText("时间", "20170730");
dc.insertText("年度", "2017");

//在书签“logo”处插入图片文件
File f1 = new File("d:/logo.png");
dc.insertImage("logo", f1);

//在书签“报表”,“统计图”处插入报表和统计图
File f2 = new File("d:/毕业去向.rpx");
FileInputStream fis = new FileInputStream(f2);
IReport report = ReportUtils.read(fis);
fis.close();
Context context = new Context();
… …
Engine engine = new Engine((ReportDefine) report, context);
report = engine.calc();
dc.insertReport("报表", report);

File f3 = new File("d:/留学.rpx");
FileInputStream fis2 = new FileInputStream(f3);
IReport report2 = ReportUtils.read(fis2);
fis2.close();
Context context2 = new Context();
… …
Engine engine2 = new Engine((ReportDefine) report2, context2);
report2 = engine2.calc();
dc.insertReport("统计图", report2);

//执行所有修改动作,然后关闭输出文件流
dc.execute();
fos.close();

至此,word 报告就自动生成了,以后每次只要执行一遍这段程序就行了,是不是方便了不少?
不过,这个办法还有个缺点,当插入内容变化时,我们就需要修改 java 代码,而改了代码之后又得重编译部署,难以做到热切换。这个办法还是不够方便。
为此,润乾报表还提供了外部配置的方法来实现 word 报表,可以预先编辑一个 xml 文件,在里面写个需要替代的书签等内容,然后程序会读取这个配置文件生成相应的 word 文档。
这样,当插入内容变化的时候,只要修改 xml 配置信息即可,而不用修改代码再编译了。我们一起来看一下:
1、编辑配置文件 xml
该文件中可配置多个书签和插入对象,当对象来源于内存时,可配置成 map,通过 key 从内存中取值,key 值可以是 IReport、byte[]、Image、String,值的类型程序会自动判断。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>











<!-- value表示报表参数值(串) -->
<reportParam name="arg1" type="value" value="设定参数1"></reportParam>
<!-- type为map时会从内存中根据name读取key,key未填写时跟name相同,key=””时会取map中key为空的值 -->
<reportParam name="arg2" type="map"></reportParam>      



<?xml version="1.0" encoding="UTF-8" standalone="yes"?>











<!-- value表示报表参数值(串) -->
<reportParam name="arg1" type="value" value="设定参数1"/>
<!-- type为map时会从内存中根据name读取key,key未填写时跟name相同,key=””时会取map中key为空的值 -->
<reportParam name="arg2" type="map"/>      


注:在 web 应用中,如果 web.xml 里配置了 reportServlet,那么程序会自动加载 raqsoftconfig.xml,读取该文件里配置的 reportFileHome,数据源信息,授权文件等信息。
2、根据配置信息生成 Word 文档
try{

File of = new File("D:/out.docx");//输出文件
… …
FileOutputStream fos = new 
FileOutputStream(of);

//加载xml,batch.xml内容如上一小节所示
String xmlConfig = DocxChanger.xmlFile2String("D:/batch.xml");

//当插入的对象来自内存,比如IReport对象
File f4 = new File("d:/留学.rpx");
FileInputStream fis = new FileInputStream(f4);
IReport report = ReportUtils.read(fis);
fis.close();
Context context = new Context();
Engine engine = new Engine((ReportDefine) 
report, context);
report = engine.calc();

//当对象来源于内存时,可配置成 map
HashMap map =new HashMap();
map.put("f", report);//设置xml中key为f的值
map.put("arg2", "2014-12-15 12:00:23");//当插入对象来自内存,比如String,设置xml中key为arg2的值

DocxChanger.insert(map, xmlConfig, fos);
fos.close();

}catch(Throwable x) {

x.printStackTrace();

}
try{

File of = new File("D:/out.docx");//输出文件
… …
FileOutputStream fos = new 
FileOutputStream(of);

//加载xml,batch.xml内容如上一小节所示
String xmlConfig = DocxChanger.xmlFile2String("D:/batch.xml");

//当插入的对象来自内存,比如IReport对象
File f4 = new File("d:/留学.rpx");
FileInputStream fis = new FileInputStream(f4);
IReport report = ReportUtils.read(fis);
fis.close();
Context context = new Context();
Engine engine = new Engine((ReportDefine) 
report, context);
report = engine.calc();

//当对象来源于内存时,可配置成 map
HashMap map =new HashMap();
map.put("f", report);//设置xml中key为f的值
map.put("arg2", "2014-12-15 12:00:23");//当插入对象来自内存,比如String,设置xml中key为arg2的值

DocxChanger.insert(map, xmlConfig, fos);
fos.close();

}catch(Throwable x) {

x.printStackTrace();

}

说了这么多,大家肯定会觉得理想很丰满,现实很骨感,这个功能是很完美,确实可以帮我解决这些个棘手的问题,但是都知道报表工具价格昂贵,再加上这样小奢的功能,岂不是贵上加贵,为此特意买一套昂贵的报表工具,似乎就不划算了,而开源报表里面又没有这个功能。但是你不知道的是,现在报表工具已经低端化了,润乾率先开始了 5000 元 / 套的低价报表了,恰巧这个功能里面有,恰巧你还看到了。

作者:yangcl
链接:http://c.raqsoft.com.cn/article/1533027654063?r=IBelieve
来源:乾学院
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

目录
相关文章
|
网络协议 Linux 网络架构
【Cisco Packet Tracer】构造超网
【Cisco Packet Tracer】构造超网
201 0
|
7天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
6天前
|
存储 人工智能 Java
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
本文讲解 Prompt 基本概念与 10 个优化技巧,结合学术分析 AI 应用的需求分析、设计方案,介绍 Spring AI 中 ChatClient 及 Advisors 的使用。
318 130
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
|
18天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1331 8
|
5天前
|
监控 JavaScript Java
基于大模型技术的反欺诈知识问答系统
随着互联网与金融科技发展,网络欺诈频发,构建高效反欺诈平台成为迫切需求。本文基于Java、Vue.js、Spring Boot与MySQL技术,设计实现集欺诈识别、宣传教育、用户互动于一体的反欺诈系统,提升公众防范意识,助力企业合规与用户权益保护。
|
17天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
1412 87
|
6天前
|
人工智能 Java API
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
本文介绍AI大模型的核心概念、分类及开发者学习路径,重点讲解如何选择与接入大模型。项目基于Spring Boot,使用阿里云灵积模型(Qwen-Plus),对比SDK、HTTP、Spring AI和LangChain4j四种接入方式,助力开发者高效构建AI应用。
312 122
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)