作者:cleverpig(http://blog.matrix.org.cn/page/cleverpig)

前言:
        近日,事务繁忙,无暇写作,正式声明并非“封笔”。愿对诸位matrixer兄弟能予以善意的谅解。早在去年的某个时候,本人钻研“Jacob”时写下了篇有关“Jacob生成pdf文档”的文章发表在Matrix上,不时收到热心开发者的Ask,问题集中于Jacob的要害——开发难度大。对于不熟知.net和java技术的开发者,若想领会文中的含义,谈何容易(幸亏当时本人瞥了瞥.net),不然一头雾水更无法行文讲解了。面对Jacob冷峻的面庞,cleverpig不禁慨叹:“中国人历来有刻骨铭心的苦难史,就不要让程序员再来过了吧。”
        此问题藏于脑中,时时煎熬,不想一日终有斩获便持执笔写来和大家共享。

软件准备:
        OO:是OpenOffice的简称,而非众人皆知的面向对象,有关它的开发文档有好几沓,在此不多言了。别忘了先安装一下啊,否则无法进行类型转换的。OO支持的文档类型:odt、ods等,对应熟知的Office文档类型:doc、xls。
JOOReports:是基于OO文档模版的文档生成软件,支持动态替换和freemarker EL、Collection的文档重复替换,附随源代码提供了比较精简的api和doc,但源代码中的example很值得一看。
JOOConvert:毋庸置疑就是配套的文档转换软件,将文档托管给OO进行转换,然后获得转换后的文档,支持多种类型文档:odt、ods、doc、rtf、txt、pdf、xls。后面的代码中有详细介绍。

代码框架:
        信手写来也称不上“框架”,总体上分了三部分:调用JOOReports/JOOConvert的核心类、基于Strieps框架的web实现、必不可少的UnitTest。
        核心部分:
        DocumentTemplateParam:文档生成参数类。
        DocumentConvertParam:文档转换参数类。
        ConvertContext:用于连接OO网络服务的转换上写文类。
        DocumentGenerator:文档生成类。
        DocumentFormatConverter:文档格式转换类。
之所以分如此细致,也许是本人的“重构癖”作祟吧。但扩展起来是很具灵性的。如果Martin Flower大人看到,可能感激落泪吧。

Web实现:很简单的Stripes框架实现的产品登记输出为doc、pdf、xls格式的文件,在此抛砖引玉啦。
        Product:产品Bean类。
        ProductDetailActionBean:实现产品登记的ActionBean类。
        WEB-INF/fileTemplate:odt、ods文档模版保存位置。

UnitTest:对核心部分进行测试,当然Stripes也可作测试,但应用简单懒于编写了。

编写文档模版:
        OO在设计时考虑了通用性,所以每个odt、ods文件都是以zip的压缩模式保存,只要用相关软件便可以观其状了。Content.xml尤为重要,其中保存了模版数据,如hello-template.odt:

<?xml version="1.0" encoding="UTF-8"?>
<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" office:version="1.0"><office:scripts/><office:font-face-decls><style:font-face style:name="Tahoma1" svg:font-family="Tahoma"/><style:font-face style:name="Tahoma" svg:font-family="Tahoma" style:font-pitch="variable"/><style:font-face style:name="瀹嬩綋" svg:font-family="瀹嬩綋" style:font-pitch="variable"/><style:font-face style:name="Times New Roman" svg:font-family="&apos;Times New Roman&apos;" style:font-family-generic="roman" style:font-pitch="variable"/><style:font-face style:name="Arial" svg:font-family="Arial" style:font-family-generic="swiss" style:font-pitch="variable"/></office:font-face-decls><office:automatic-styles><style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard"><style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/><style:text-properties fo:font-weight="bold" style:language-asian="zh" style:country-asian="CN" style:font-weight-asian="bold" style:font-weight-complex="bold"/></style:style><style:style style:name="P2" style:family="paragraph" style:parent-style-name="Standard"><style:text-properties style:language-asian="zh" style:country-asian="CN"/></style:style><style:style style:name="T1" style:family="text"><style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/></style:style></office:automatic-styles><office:body><office:text><text:sequence-decls><text:sequence-decl text:display-outline-level="0" text:name="Illustration"/><text:sequence-decl text:display-outline-level="0" text:name="Table"/><text:sequence-decl text:display-outline-level="0" text:name="Text"/><text:sequence-decl text:display-outline-level="0" text:name="Drawing"/></text:sequence-decls>
<text:p text:style-name="P1">浜у搧娉ㄥ唽琛?/text:p>
<text:p text:style-name="P2"><text:span text:style-name="T1">娉ㄥ唽浜猴細</text:span>${userName}[#if userName="cleverpig"],haha[/#if]</text:p>
[#list productList as prod]
<text:p text:style-name="P2">
<text:span text:style-name="T1">浜у搧鍚嶇О锛?/text:span>${prod.name}
<text:span text:style-name="T1">浜у搧缂栧彿锛?/text:span>${prod.number}
</text:p>
[/#list]
</office:text></office:body></office:document-content>

其中的乱码是因UTF-8编码造成。文档风格就是xml分割,但其中红色代码使用了freemarker的表达式风格,这也是JOOReport所支持的。具体详见freemarker和JOOConvert manual。编写模版时,建议使用设计好格式的文档,然后使用文本编辑器在其中插入表达式,切勿在OO中直接编写表达式,因为OO会对其进行转换,使其失效。

转换文档时启动OO后台服务:
        在调用JOOReport生成文档时无需启动OO,因为与OO服务无关;而调用JOOConvert进行文档转换时就需要在控制台中输入一下:
        cd %OPENOFFICE_HOME%/program
        soffice.exe -headless -accept=socket,port=8100,host=localhost;urp

OPENOFFICE_HOME代表了OO安装时的目录。

代码下载:
        由于代码很完整,size为7M,所以分为了6份:
        [下载文件]
        [下载文件]
        [下载文件]
        [下载文件]
        [下载文件]
        [下载文件]

参考资源:
JOOReports
freemarker
OpenOffice

基于OO模版技术的文档Web输出新法相关推荐

  1. Java支持latex,基于Java和LaTeX的文档自动生成技术研究

    基于Java和 LaTeX 的文档 自动生成技术研究 ◆尚宝欣 徐 屹 (东北电力大学理学院,吉林 长春 132012) [摘 要]讨论了结合Java与LaTex 自动生成 PDF文档的方法.针 展名 ...

  2. 基于java的汽车管理系统+文档

    博主介绍:✌在职Java研发工程师.专注于程序设计.源码分享.技术交流.专注于Java技术领域和毕业设计✌ 项目名称 基于java的汽车管理系统+文档 视频效果 https://www.bilibil ...

  3. [转载]JBoss技术支持文档

    JBoss技术支持文档 1.本节内容简介 本章主要介绍JBOSS(免费的EJB服务器),以及教会大家如何安装Jboss,建立你第一个EJB和客户端.关于什么是EJB,以及如何开发等.这些关于EJB方面 ...

  4. 基于Apriori算法的Nginx+Lua+ELK异常流量拦截方案 郑昀 基于杨海波的设计文档(转)...

    郑昀 基于杨海波的设计文档 创建于2015/8/13 最后更新于2015/8/25 关键词:异常流量.rate limiting.Nginx.Apriori.频繁项集.先验算法.Lua.ELK 本文档 ...

  5. 基于 TensorFlow 在手机端实现文档检测

    手机端运行卷积神经网络的一次实践 - 基于 TensorFlow 和 OpenCV 实现文档检测功能 1. 前言 本文不是神经网络或机器学习的入门教学,而是通过一个真实的产品案例,展示了在手机客户端上 ...

  6. 论文阅读|基于领域知识图谱的多文档摘要生成与应用

    论文地址:基于领域知识图谱的多文档摘要生成与应用 先验知识 1.多文档摘要技术: (理解:类似于每篇文章的摘要.关键词,方便通过标签筛选是否是你需要的内容) 利用计算机将同一主题下或者不同主题下的多篇 ...

  7. 一份完整齐全的技术方案文档

    2022年-[归一计划三期-用户中心三期第二阶段]技术方案 部门:基础架构部 时间:2022.02.25 1.背景 描述技术方案的背景 由于历史原因,旧服务存在很多代码不规范.冗余度高.扩展性差等问题 ...

  8. 基于OpenVINO与PP-Strucutre的文档智能分析 - 飞桨AI Studio

    ★★★ 本文源自AlStudio社区精品项目,[点击此处]查看更多精品内容 >>> 基于OpenVINO与PP-Strucutre的文档智能分析 本示例包含以下部分组成: 项目说明 ...

  9. java改写模式_Java基于状态模式实现的文档编辑模式切换功能实例

    本文实例讲述了Java基于状态模式实现的文档编辑模式切换功能.分享给大家供大家参考,具体如下: 一 模式定义 状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来就像是改变了其类. 二 ...

最新文章

  1. NSThread Run Loop
  2. 推荐一个很好用的脚本session snapper
  3. js读取本地excel文档数据
  4. MxNet 迁移学习实现深度学习分类
  5. 微信登录画面_微信登录界面改版,美炸了!
  6. centos 7 菜鸟第一天 双启动
  7. andriod数据库的开发
  8. laravel连接mysql8_php – 如何使用laravel运行MySql 8?
  9. 传说中的世界500强面试题-
  10. 内容创作费时费力?这款AI写作神器超给力!
  11. Eclipse美化操作
  12. CSV文件使用Excel打开
  13. CppCheck的使用
  14. 一分钟建立自己单位的故障报修平台
  15. android刷新时的圆形动画_Android 实现倒计时动画效果
  16. 第4章 点云的滤波与分类 4.1点云数据的过滤
  17. python-docx 不改变原文件调整段落行间距的问题
  18. win10设置默认浏览器反复无常的解决方案
  19. 《Android 应用案例开发大全(第3版)》——第2章,第2.1节壁纸的背景及功能概述...
  20. ms10_018_ie_behaviors漏洞复现

热门文章

  1. 设备树的引进与体验_使用设备树时的驱动编程
  2. 【长期更新】咨询分析中的n个真实数据处理场景
  3. mysql实验程序设计与游标_实验十三 T-SQL程序设计及游标设计.doc
  4. linux 配置免密码登录,Linux - 配置SSH免密登录 - “ssh-keygen”的基本用法
  5. 【kong系列八】之HMAC认证hmac-auth插件
  6. 【2023年第十一届泰迪杯数据挖掘挑战赛】B题:产品订单的数据分析与需求预测 23页论文及实现代码
  7. 一个简陋至极的员工考勤系统
  8. 用电量专题-全国、煤炭行业、地级市工业用电量等多指标(部份内容已更新至2021)
  9. MySQL 数据库存储藏文 Incorrect string value
  10. python将灰度图保存为8bit彩色图