Web开发中的报告输出(rtf、xls)

Plux posted @ 2013年5月23日 11:20 in Default with tags .net php java 文档导出 , 2712 阅读

这几天碰到一个看起来比较难处理的一个任务:把数据库中的数据导出为可以打印或者方便办公软件查看的格式。

这是对文档类型输出中,最近解决的一个方法。我考虑到这里大家主要是使用 PDF 输出和 Doc 格式的输出,但是 PDF 格式和 Doc 格式输出都不是很靠谱。其实简单的方法就是利用 RTF 格式进行中转输出。因为 RTF 格式实际上和 HTML 格式类似,也采用文本格式存储并且用文本标签描述的方式为文本添加显示属性,纯文本的操作能够更清楚地考虑进行的操作,错误恢复也会比二进制格式的 PDF 和 Doc 好点。

由于是一个打印文档,或者带有一定格式的文档,发现大家主要采用模版替代的方案。即先把文档编辑好,然后需要填写的内容用一些特殊的文本进行标记。在输出的时候,先读取文本,然后替代预先设置好的文本标记为要输出的内容即可。

Word 格式的输出

Word 格式输出是一个很不明确的说法,大概指的是可以用 Word (Microsoft Word 以及类似软件)打开的格式吧。这种格式的输出大概是为了打印而准备的。由于HTML天生没过多地考虑页面打印的问题。以前做过利用 CSS 的媒体类型来做的打印功能,大家说总是不那么方便。

直接导出 doc 格式文件是首选的。如果采用的是 Java 或者 .NET 平台,这个是一个好消息,因为很多人已经做过这方面的尝试了。比较好用的库有 Apache POI(For Java)以及对应的 .NET 版本 NPOI (For .NET)。

在 PHP 或者其他脚本语言(例如 Python 等)就没找到比较好用的库了,有谁了解的给我留个言吧。但是,临时的解决方法也不是没有,可以尝试输出 RTF 文件格式。这种文件格式和 HTML 类似,也是用纯文本编码,用标记来为文本添加格式等(只是标记不一样)。因此,只需要编辑好模板 Word 文件,然后保存为 RTF 格式,然后要输出的时候,把这个 RTF 格式的文件直接读入,然后进行字符串替换就好了。

不过,需要注意的是,由于格式化标签的存在,你输出的替代文本可能不是连着的(参考一下 HTML 代码,对于 RTF 来说也有类似的问题,只是标签格式不一样),文本替换的时候也很难发现,导致输出的时候根本替换不了。

例如,你用来做模板替换的内容是 \$PLACEHOLDER\$ 而实际上,在文件中表达却是:







<span><span>$</span><span>PLACEHOLDER</span><span>$</span></span>

这个问题实际上就是无效格式相互嵌套,显示效果还是无效格式的情况。或许可以用离散数学里面的关系给它命名为“幂等性”(这也是常说的,工具生成冗余代码的原因)。所以,在考虑输出的时候一定要先考察模板文件是否存在这个情况。

对于简单的情况,使用 RTF 格式或许更易于排错

XLS 输出

越来越觉得 XLS 是一种重要的格式。虽然不是什么标准,但是,非技术人员都对这种表格形式的格式十分熟悉,而且用户体验也比较好。所以,作为一种数据交流格式,输出 XLS 是一种不错的选择。而业界似乎对 XLS 格式已经做了很多研究了,很多语言都有对应的版本读写库。

在 Java/.NET 平台中,还是采用 Apache POINPOI For .NET)库。这个库的两个版本对 XLS 读写支持都是很完善的,不过对于 .NET 平台还可以采用微软官方的库(可能依赖 Microsoft Office 以及其授权)。

在 PHP 中可以采用 PHPExcel 库,这个库可以输出包括 Excel 97~2003 格式的xls格式,还可以输出类似的 xlsx 格式和 ods 格式。


现在发现,其实这些格式在深入研究以后都不是很困难,即使是非文本格式的,其实也是采用附加格式进行编码的,而困难在于了解其编码的方式。

有更好的解决方案或者更好的库推荐可以留言提出来,帮助更多有需要的人。:)

Avatar_small
依云 说:
May 24, 2013 10:55:33 AM

Word 才不是用来打印的呢。用来打印的是 pdf 或者 ps。
HTML 天生考虑了不同媒介的,没考虑的是浏览器啦。所以要打印 HTML 就用 princexml 转成 PDF 再打印。

另外,你为什么非要找 PHP 的库呢?不会进程间通信么?

Avatar_small
Plux 说:
May 24, 2013 11:04:22 PM

@依云: HTML考虑的媒介我也知道,但也是后来的事了吧,最初的 HTML 应该没考虑多媒介支持的。而且大多数用户也不知道,浏览器考虑也不完善。
至于 Word 格式(或者 RTF),我知道它们在业界的评价都不好,但是它们却能给用户最直观的体验。而 RTF 作为纯文本型富文本格式的一种,本来就考虑到打印的一些特性(虽然不全面,但是一般用户应该是够用了)。
我是基于以上考虑,才使用这两种格式的。
至于其他的库,后者更简易的输出格式,希望指教。

Avatar_small
依云 说:
May 24, 2013 11:21:55 PM

@Plux: Python 好像是有 rtf 的库的啦。
另外,只打印用的话完全可以生成 PDF 的嘛。

Avatar_small
Plux 说:
May 24, 2013 11:40:18 PM

@依云: 搜索了一下,Python应该是有 rtf 读写的相关库的,不过其实也不用那么复杂。自己写一个文本替换函数即可。因为 RTF 是纯文本的,因此对文本替换也很友好。只是需要注意 无效标签使得文本不连续 而导致替换文本的时候出错 的问题。
PDF 生成有点麻烦,特别是在给定一个复杂排版的模板时。而且 PDF 似乎不是纯文本的格式,不容易调试,不过有心输出还是可以的……感觉 PHP 的库真有点换乱,找到一个关于 PDF 的文档(http://justcoding.iteye.com/blog/601108,有 HTML 转 PDF 的,但未实际测试)。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter