DynamicReports动态生成PDF
cnspider 发布于85月前 0答/7476阅

项目中需要用到PDF报表,找寻了好久最后找到的DynamicReports,这个报表是依托JasperReport动态生成报表的,很适合我。下面分享一下如何在eova项目中使用。

First,添加引入,pom.xml添加DynamicReports的依赖,在其官网下载demo就知道需要哪些包了,再此不多说。。。

引入依赖之后我门就可以开始业务了,因为DynamicReports的PDF输出需要 response.getOutputStream(),所以我们需要自定义一个render


public class XXXPrintRender extends Render {
        @Override
	public void render() {
        }
}

然后在自定义的XXXPrintRender类的render方法中生成报表


OutputStream os = null;
try {					
	StyleBuilder boldStyle = stl.style().bold();			
	StyleBuilder boldCenteredStyle = stl.style(boldStyle).setHorizontalTextAlignment(HorizontalTextAlignment.CENTER);
	StyleBuilder titleStyle = stl.style(boldCenteredStyle)
			.setVerticalTextAlignment(VerticalTextAlignment.MIDDLE)
			.setFontSize(9);
	
	os = response.getOutputStream();
	JasperReportBuilder jasbuild = report()
	  .setColumnTitleStyle(stl.style().setFontSize(9))
	  .addColumn(col.reportRowNumberColumn("行号").setFixedWidth(30).setStyle(stl.style().setFontSize(9)));
	  //根据传递过来列建立报表列,begin
		for (int i = 0; i < items.size(); i++) {
			MetaField item = items.get(i);
			jasbuild.addColumn(col.column(item.getCn(), item.getEn(), DataTypes.stringType()).setWidth(item.getInt("width")*663/(twidth-100)).setStyle(stl.style().setFontSize(8)));
			colen.add(item.getEn());
		}
	  //根据传递过来列建立报表列,end
	  jasbuild.title(
			  cmp.horizontalList()
				.add(cmp.text(object.getName()).setStyle(titleStyle).setHorizontalTextAlignment(HorizontalTextAlignment.RIGHT))
				.newRow()
				.add(cmp.filler().setStyle(stl.style().setTopBorder(stl.pen2Point())).setFixedHeight(2)))
	  .pageFooter(cmp.pageXslashY().setStyle(boldCenteredStyle))
	  .setDataSource(createDataSource())
	  .summary(cmp.horizontalList().newRow()
	  .add(cmp.filler().setStyle(stl.style().setTopBorder(stl.pen2Point())).setFixedHeight(10)))			
	  .setLocale(Locale.CHINESE)
	  .setPageFormat(PageType.PMTPRINT)
	  .toPdf(os);
} catch (Exception e) {
	throw new RenderException(e);
} finally {
	try {
		if (os != null) {
			os.flush();
			os.close();
		}
	} catch (IOException e) {
		LogKit.error(e.getMessage(), e);
	}

}		

创建两个辅助函数在XXXPrintRender类中


private JRDataSource createDataSource() {
	String[] te = (String[]) colen.toArray(new String[0]);
	DRDataSource dataSource = new DRDataSource(te);
	int row = 1;
	// 写入数据行
	for (; row <= data.size(); row++) {
		Record record = data.get(row - 1);
		// 获取当前行数据
		dataSource.add(getValues(items, record));
	}
	return dataSource;
}
	
private static Object[] getValues(List items, Record record) {
	Object[] list = new Object[items.size()];
	int i = -1;
	for (MetaField item : items) {
		i++;
		Object value = record.get(item.getEn());
		if (value == null) {
			continue;
		}
		
		switch (item.getDataType()) {
		case 7:
			String string = Convert.toBigDecimal(value).stripTrailingZeros().toPlainString();
			list[i] = string.equals("0.0")?"0":string;
			break;
		case 91:
			String val = value.toString();
			val = val.replace("-", "");
			list[i]=val.toString().substring(2, val.length());
			break;
		default:
			list[i]=value.toString();
			break;
		}
	}
	return list;
}

还有别忘记传值进来


private final MetaObject object;
private final List items;
private final List data;
private final int twidth;
private List colen = new ArrayList();

public XXXPrintRender(PrintRenderBuildService printRenderBuildService) {
	this.data = printRenderBuildService.getData();
	this.items = printRenderBuildService.getFields();
	this.object = printRenderBuildService.getObject();
	this.twidth = printRenderBuildService.getTotalwidth;
}

我的业务可能跟你们的不同,具体如何传值,还有render类中大家可以自己按照自己的业务写

打开的效果就如图所示(chrome浏览器下效果),我表里数据都清空了。呵呵,就当有数据就好了。


初次写,不好不要喷啊!


提交评论