通过Email推送统计报告。一般除了要求将PPT报告文件作为附件发给用户,同时希望将报告内容在邮件中直观展示。 一份统计报告中经常包含柱状图、饼图、好看的图表,这些信息要直接在Email中展示比较复杂。本文推荐一种方式:将PPT图表内容转换为高保真的图片,将图片放到Email中发送,在不丢失用户体验的前提下,工作量尽可能小。
一、 将PPT报告转换为PNG图片文件。
有两种方式:一种是采用POI组件将图片绘制到剪切板再输出为图片文件;另一种方式是通过COM接口调用PowerPoint的接口,使用PPT自身的”另存为”功能,将PPT内容另存为图片文件。
优劣比较:
1) POI组件:不依赖于Office, 再linux下也可以执行;不好的地方是保存的图片效果太差,文字模糊,图表存在重影。参考代码:http://blog.csdn.net/jsudavid/article/details/10387959。输出图片文件效果如博客中描述。本人POI组件应用经验比较少,不清楚如何优化,有经验的同行可以给点建议。
2) COM接口:依赖于Office,需要安装Office,只能部署在Windows平台,性能比较低,不支持并发操作(注意添加同步锁);导出的图片效果很好,功能强大,代码简单。
参考代码:
public static void main(String[] args)
{
new PPT2Image().SaveAsImage("D:\\TEMP\\ppt\\xxx.pptx",
"D:\\TEMP\\ppt\\20151201");
}
/**
*
* 保存PPT为图片文件,每一个Slide保存为一个图片文件。
*
* @param pptFilePath ppt文件路径。
* @param savePath 保存图片文件目录,生成的图片文件放该目录下。
*/
public synchronized void SaveAsImage(String pptFilePath, String savePath)
{
// 启动 office PowerPoint程序
ActiveXComponent pptApp = new ActiveXComponent("PowerPoint.Application");
Dispatch.put(pptApp, "Visible", new Variant(true));
Dispatch presentations = pptApp.getProperty("Presentations").toDispatch();
// 打开PPT文件
Dispatch presentation = Dispatch.call(presentations, "Open", pptFilePath, false,
false, true).toDispatch();
// 另存储为PNG图片文件。SaveAs支持将PPT保存为各种格式的文件。
// PpSaveAsFileType:18-保存为PNG格式的图片。MsoTriState:1-转换状态
// 完整的枚举定义参见MicroSoft说明文档:
// https://technet.microsoft.com/zh-cn/windows/bb251061(v=msdn.10).aspx
// https://technet.microsoft.com/zh-cn/aa432714(v=office.12)
Dispatch.call(presentation, "SaveAs", savePath, 18, 1);
// 保存,关闭文件。退出power point程序。
Dispatch.call(presentation, "Save");
Dispatch.call(presentation, "Close");
Dispatch.call(pptApp, "Quit");
}
如果POI能否做一些调优,效果达到COM接口输出的图片效果。优先使用POI组件,否则选择COM接口的方式。毕竟需要优先保证用户体验。
二、 将图片添加到邮件正文
2.1 原理描述
将PPT转换后的图片文件存储在Tomcat的Web应用路径下,提供域名(或者IP地址)下载该图片文件。用户打开收到的邮件时会通过http协议请求加载图片文件。需要注意的是中文版本的PPT转换后的PNG图片名中包含中文,要将Tomcat的资源定位编码设置为UTF-8。Conf\ server.xml。
图片文件在服务器上按日期、按类型长期保存,提供下载服务。如果Tomcat服务器关闭了,用户打开邮件就看不到图片。
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL HTTP/1.1 Connector on port 8080
-->
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
2.2 参考代码
email.setMailHeader("Email推送报告技术说明及样例代码");
mailContext += "创建人: Elon";
mailContext += "<br />"
+ "<br />"
+ "本文档主要解决报告转换为图片, 添加到Email正文发送的问题。"
+ "<br />"
+ "<br />";
mailContext += "<img src=http://192.168.1.1:80/app/images/report/幻灯片3.PNG />";
mailContext += "<br />"