在Web上用iText和JFreeChart将图形报表导出到PDF

最近项目中需要一个将生成的图形报表导出到PDF文件的功能。在图形上面本打算采用Flash进行展示,可是没有找到怎样直接将Flash导入PDF的方法,应该只有先生成图片才可以吧?(知道怎样做的大侠可以给个方法,先谢了。)于是改用JFreeChart来画图。生成PDF方面工具也很多,iText还比较成熟,于是选用它来生成PDF。

一开始本想图个省事,直接将网页转换成PDF文件。但是了n次后发现,这样的做法会导致图表严重变形,根本没法看,没办法,看来只能利用iText的API一点一点的做了。还好,iText的确够强大。就目前来看,完全可以处理项目的需求。下面就是我用iText结合JFreeChart在Web中将图表转换为PDF的方法。

本项目采用Struts2,分两个方法来处理,一个叫exportDeviceStat,调用它导出PDF,另一个叫getJFreeChart,调用它生成图形。下面直接上代码了:





/**

Java代码
1. * 将图表导出到PDF
2. * @return
3. */
4.public String exportDeviceStat() {
5. HttpServletResponse response = ServletActionContext.getResponse();
6.
7. String fileTitle = year + "年" + month + "月各办公区设备运行情况统计";
8.
9. response.setContentType("application/pdf;charset=utf-8");
10. response.addHeader("Content-Disposition", "attachment;filename=" + encodeFilename(fileTitle) + ".pdf");
11.
12. //获得办公区列表
13. List<Location> locationList = SystemCache.getLocationListFromCache();
14.
15. if (null != locationList && locationList.size() > 0) {
16.
17. //创建Document对象
18. Document document = new Document();
19.
20. try {
21. //创建PDF对象实例,直接输出到网页上
22. PdfWriter.getInstance(document, response.getOutputStream());
23.
24. //设置文档字体
25. BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", false);
26. com.lowagie.text.Font fontChinese = new com.lowagie.text.Font(bfChinese, 12, com.lowagie.text.Font.NORMAL, Color.BLACK);
27.
28. // 添加PDF文档的一些信息
29. document.addTitle(fileTitle);
30. document.addAuthor("设备运行情况统计");
31. document.addSubject("");
32. document.addKeywords("");
33. document.addCreator("设备运行情况统计");
34.
35. HeaderFooter footer = new HeaderFooter(new Phrase(" 第", fontChinese), new Phrase("页 ", fontChinese));
36. footer.setBorder(Rectangle.NO_BORDER);
37. footer.setAlignment(Element.ALIGN_RIGHT);
38. document.setFooter(footer);
39.
40. // 打开文档,将要写入内容
41. document.open();
42.
43. // 文档标题标题
44. document.add(new Paragraph(fileTitle, fontChinese));
45.
46. // 换行
47. document.add(Chunk.NEWLINE);
48.
49. // 插入表格
50. com.lowagie.text.Font f8 = new com.lowagie.text.Font(bfChinese, 8, com.lowagie.text.Font.BOLD);
51. com.lowagie.text.Font f12 = new com.lowagie.text.Font(bfChinese, 12, com.lowagie.text.Font.BOLD);
52.
53. //生成每个办公区的统计报表
54. for (Location location : locationList) {
55. //生成一个2列的表格
56. PdfPTable table = new PdfPTable(2);
57.
58. // 宽度定位100%
59. table.setWidthPercentage(100);
60. table.setHorizontalAlignment(PdfPTable.ALIGN_LEFT);
61.
62. // 创建第一行
63. PdfPCell cell = new PdfPCell();
64. cell.setBorderColor(new Color(255, 255, 255));
65. cell.setBackgroundColor(new Color(24, 198, 248));
66. cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
67. cell.setColspan(2);
68. cell.setVerticalAlignment(PdfPCell.ALIGN_CENTER);
69.
70. //第一行中显示的文字
71. cell.setPhrase(new Paragraph(location.getLocationName() + "办公区设备运行情况统计", f12));
72. table.addCell(cell);
73.
74. //插入统计图
75. PdfPCell newcell = new PdfPCell();
76.
77. newcell.setBorderColor(new Color(255, 255, 255));
78. //设备故障率统计,JFreeChart生成图表并返回
79. Image img = Image.getInstance("http://localhost:8080/DeviceStat/getJFreeChart.html?method=getDeviceNormalCount&locationId=" + location.getLocationId() + "&year=" + year + "&month=" + month);
80. img.setAbsolutePosition(0, 0);
81. newcell.setImage(img);
82. table.addCell(newcell);
83.
84. //故障类型统计,JFreeChart生成图表并返回
85. img = Image.getInstance("http://localhost:8080/DeviceStat/getJFreeChart.html?method=getDeviceAbnormalCount&locationId=" + location.getLocationId() + "&year=" + year + "&month=" + month);
86. img.setAbsolutePosition(0, 0);
87. newcell.setImage(img);
88. table.addCell(newcell);
89.
90.
91. document.add(table);
92. }
93.
94. } catch (DocumentException de) {
95. System.err.println(de.getMessage());
96. } catch (IOException ioe) {
97. System.err.println(ioe.getMessage());
98. } finally {
99. // 关闭打开的文档
100. document.close();
101. }
102. }
103. return NONE;
104.}
* 将图表导出到PDF
* @return
*/
public String exportDeviceStat() {
HttpServletResponse response = ServletActionContext.getResponse();

String fileTitle = year + "年" + month + "月各办公区设备运行情况统计";

response.setContentType("application/pdf;charset=utf-8");
response.addHeader("Content-Disposition", "attachment;filename=" + encodeFilename(fileTitle) + ".pdf");

//获得办公区列表
List<Location> locationList = SystemCache.getLocationListFromCache();

if (null != locationList && locationList.size() > 0) {

//创建Document对象
Document document = new Document();

try {
//创建PDF对象实例,直接输出到网页上
PdfWriter.getInstance(document, response.getOutputStream());

//设置文档字体
BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", false);
com.lowagie.text.Font fontChinese = new com.lowagie.text.Font(bfChinese, 12, com.lowagie.text.Font.NORMAL, Color.BLACK);

// 添加PDF文档的一些信息
document.addTitle(fileTitle);
document.addAuthor("设备运行情况统计");
document.addSubject("");
document.addKeywords("");
document.addCreator("设备运行情况统计");

HeaderFooter footer = new HeaderFooter(new Phrase(" 第", fontChinese), new Phrase("页 ", fontChinese));
footer.setBorder(Rectangle.NO_BORDER);
footer.setAlignment(Element.ALIGN_RIGHT);
document.setFooter(footer);

// 打开文档,将要写入内容
document.open();

// 文档标题标题
document.add(new Paragraph(fileTitle, fontChinese));

// 换行
document.add(Chunk.NEWLINE);

// 插入表格
com.lowagie.text.Font f8 = new com.lowagie.text.Font(bfChinese, 8, com.lowagie.text.Font.BOLD);
com.lowagie.text.Font f12 = new com.lowagie.text.Font(bfChinese, 12, com.lowagie.text.Font.BOLD);

//生成每个办公区的统计报表
for (Location location : locationList) {
//生成一个2列的表格
PdfPTable table = new PdfPTable(2);

// 宽度定位100%
table.setWidthPercentage(100);
table.setHorizontalAlignment(PdfPTable.ALIGN_LEFT);

// 创建第一行
PdfPCell cell = new PdfPCell();
cell.setBorderColor(new Color(255, 255, 255));
cell.setBackgroundColor(new Color(24, 198, 248));
cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
cell.setColspan(2);
cell.setVerticalAlignment(PdfPCell.ALIGN_CENTER);

//第一行中显示的文字
cell.setPhrase(new Paragraph(location.getLocationName() + "办公区设备运行情况统计", f12));
table.addCell(cell);

//插入统计图
PdfPCell newcell = new PdfPCell();

newcell.setBorderColor(new Color(255, 255, 255));
//设备故障率统计,JFreeChart生成图表并返回
Image img = Image.getInstance("http://localhost:8080/DeviceStat/getJFreeChart.html?method=getDeviceNormalCount&locationId=" + location.getLocationId() + "&year=" + year + "&month=" + month);
img.setAbsolutePosition(0, 0);
newcell.setImage(img);
table.addCell(newcell);

//故障类型统计,JFreeChart生成图表并返回
img = Image.getInstance("http://localhost:8080/DeviceStat/getJFreeChart.html?method=getDeviceAbnormalCount&locationId=" + location.getLocationId() + "&year=" + year + "&month=" + month);
img.setAbsolutePosition(0, 0);
newcell.setImage(img);
table.addCell(newcell);


document.add(table);
}

} catch (DocumentException de) {
System.err.println(de.getMessage());
} catch (IOException ioe) {
System.err.println(ioe.getMessage());
} finally {
// 关闭打开的文档
document.close();
}
}
return NONE;
}

/**

Java代码
1. * 用JFreeChart生成统计图
2. * @return
3. */
4.public String getJFreeChart() {
5. HttpServletResponse response = ServletActionContext.getResponse();
6.
7. response.setContentType("image/jpeg;charset=utf-8");
8.
9. //获得办公区信息
10. Location location = SystemCache.getLocationByIdFromCache(locationId);
11.
12. if (null != location) {
13. DefaultPieDataset data = getDataSet(method, locationId, year, month);
14. JFreeChart chart = ChartFactory.createPieChart("getDeviceNormalCount".equals(method) ? "办公区设备运行情况统计" : "故障类型分布", data, true, false, false);
15.
16. chart.setBorderPaint(new Color(255,255,255));
17. chart.setBorderVisible(false);
18. chart.getTitle().setFont(new Font("宋体", Font.BOLD,12));
19. chart.getLegend().setItemFont(new Font("宋体", Font.BOLD,12));
20. PiePlot piePlot= (PiePlot) chart.getPlot();//获取图表区域对象
21. piePlot.setBackgroundPaint(new Color(255,255,255));
22. piePlot.setOutlineVisible(false); //无边框
23. piePlot.setNoDataMessage("暂无统计数据"); //设置无数据时的显示内容
24. piePlot.setLabelFont(new Font("宋体",Font.BOLD,12)); //饼图旁边的中文
25. //按百分比显示
26. piePlot.setLabelGenerator(new StandardPieSectionLabelGenerator(
27. "{0}:{2}", NumberFormat.getNumberInstance(), new DecimalFormat("0.00%")
28. ));
29.
30. try {
31. //输出图标
32. ChartUtilities.writeChartAsJPEG(response.getOutputStream(),
33. 1,chart,400,300,null);
34.
35. response.flushBuffer();
36. } catch (IOException e) {
37. // TODO Auto-generated catch block
38. e.printStackTrace();
39. } finally {
40.
41. }
42. }
43.
44. return NONE;
45.}
46.
47./**
48. * 获得JFreeChart需要的数据
49. * @param method
50. * @param locationId
51. * @param year
52. * @param month
53. * @return
54. */
55.private static DefaultPieDataset getDataSet(String method, Integer locationId, Integer year, Integer month) {
56. DefaultPieDataset dataset = new DefaultPieDataset();
57.
58. if ("getDeviceNormalCount".equals(method)) {
59. Integer normalCount = SystemCache.getDeviceStatNormalCountFromCache(locationId, year, month);
60. Integer abNormalCount = SystemCache.getDeviceStatAbnormalCountFromCache(locationId, year, month);
61.
62. if (null != normalCount && 0 != normalCount) {
63. dataset.setValue("设备正常率", normalCount);
64. }
65. if (null != abNormalCount && 0 != abNormalCount) {
66. dataset.setValue("设备故障率", abNormalCount);
67. }
68. } else {
69. List<DeviceBreakdownTypeCount> countList = SystemCache.getDeviceBreakdownTypeCountFromCache(locationId, year, month);
70. if (null != countList && countList.size() > 0) {
71. for (DeviceBreakdownTypeCount count : countList) {
72. dataset.setValue(Constant.DEVICE_BREAKDOWN_TYPE_DESC[count.getBreakdownType()], count.getBreakdownTypeCount());
73. }
74. }
75. }
76.
77. return dataset;
78.}
* 用JFreeChart生成统计图
* @return
*/
public String getJFreeChart() {
HttpServletResponse response = ServletActionContext.getResponse();

response.setContentType("image/jpeg;charset=utf-8");

//获得办公区信息
Location location = SystemCache.getLocationByIdFromCache(locationId);

if (null != location) {
DefaultPieDataset data = getDataSet(method, locationId, year, month);
JFreeChart chart = ChartFactory.createPieChart("getDeviceNormalCount".equals(method) ? "办公区设备运行情况统计" : "故障类型分布", data, true, false, false);

chart.setBorderPaint(new Color(255,255,255));
chart.setBorderVisible(false);
chart.getTitle().setFont(new Font("宋体", Font.BOLD,12));
chart.getLegend().setItemFont(new Font("宋体", Font.BOLD,12));
PiePlot piePlot= (PiePlot) chart.getPlot();//获取图表区域对象
piePlot.setBackgroundPaint(new Color(255,255,255));
piePlot.setOutlineVisible(false); //无边框
piePlot.setNoDataMessage("暂无统计数据"); //设置无数据时的显示内容
piePlot.setLabelFont(new Font("宋体",Font.BOLD,12)); //饼图旁边的中文
//按百分比显示
piePlot.setLabelGenerator(new StandardPieSectionLabelGenerator(
"{0}:{2}", NumberFormat.getNumberInstance(), new DecimalFormat("0.00%")
));

try {
//输出图标
ChartUtilities.writeChartAsJPEG(response.getOutputStream(),
1,chart,400,300,null);

response.flushBuffer();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {

}
}

return NONE;
}

/**
* 获得JFreeChart需要的数据
* @param method
* @param locationId
* @param year
* @param month
* @return
*/
private static DefaultPieDataset getDataSet(String method, Integer locationId, Integer year, Integer month) {
DefaultPieDataset dataset = new DefaultPieDataset();

if ("getDeviceNormalCount".equals(method)) {
Integer normalCount = SystemCache.getDeviceStatNormalCountFromCache(locationId, year, month);
Integer abNormalCount = SystemCache.getDeviceStatAbnormalCountFromCache(locationId, year, month);

if (null != normalCount && 0 != normalCount) {
dataset.setValue("设备正常率", normalCount);
}
if (null != abNormalCount && 0 != abNormalCount) {
dataset.setValue("设备故障率", abNormalCount);
}
} else {
List<DeviceBreakdownTypeCount> countList = SystemCache.getDeviceBreakdownTypeCountFromCache(locationId, year, month);
if (null != countList && countList.size() > 0) {
for (DeviceBreakdownTypeCount count : countList) {
dataset.setValue(Constant.DEVICE_BREAKDOWN_TYPE_DESC[count.getBreakdownType()], count.getBreakdownTypeCount());
}
}
}

return dataset;
}


最后运行的结果:
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值