使用jasperreport + ireport进行报表开发时,有客户提出这样的打印要求
报表的每一页的大小是固定的,页头和页尾保持在最上和最下,中间的数据限制只能打印五条数据,多于五条数据的,进行分页打印,少于五条数据的,打印空白表格线条
如下:
单位列表
单位名称 地址 负责人
--------------------
微软 美国 比尔盖茨
____________________
____________________
____________________
____________________
____________________
打印人:happymgp 打印时间:2008-09-27
这种报表,在jasperreport里面可以画出来,但jasperreport不能在空白行处画出表格线条,只能达到下面这种效果
单位列表
单位名称 地址 负责人
--------------------
微软 美国 比尔盖茨
____________________
打印人:happymgp 打印时间:2008-09-27
只能在有数据的地方打印出线条,没有数据的地方都是空白行
找了好久,看到网上一则文章,有兴趣可以看一下
http://www.blogjava.net/super/archive/2006/01/13/27851.html
他的解决思路是,在报表设计时,增加一个参数,在构造数据时,根据这个参数对数据进行扩充,如果数据行数不是这个参数的倍数,在数据的末尾补空行,报表设计时
注意空行的处理,就可以打印出空白行,并且有线条画出
这种简单的处理,对于没有分组要求,只是单纯的一行一行打印的报表,能满足打印
要求,但如果需要分组的话,遇到空行,分组条件就不一样,会把空行和上面的数据分在两页中进行打印
既然这个思路不能满足我要求的报表,只有自己研究一下jasperreport的原代码了
前提:
jasperreport可以控制每页打印数据的行数,只要调整好detail的高度就行
思路:
从报表填充入手,在填充新的打印页面时,检查上一个页面是否已经填充
满了,如果没有满,向上一个页面填充数据(只填充线条对象,并且不对报表进行计算),直到填充满了为止
需要改动的类:JRHorizontalFiller、JRVerticalFiller
在JRVerticalFiller类的fillReportEnd()函数和fillPageBreak()函数中,增加下
面这个函数的调用
private void fillBlankRowDetail() throws JRException {
if (log.isDebugEnabled() && !detail.isEmpty()) {
log.debug("Fill " + fillerId + ": detail");
}
if (!detail.isPrintWhenExpressionNull()) {
//calculator.estimateVariables();
detail.evaluatePrintWhenExpression(JRExpression.EVALUATION_ESTIMATED);
}
if (detail.isToPrint()) {
while ((detail.getHeight() <= columnFooterOffsetY - offsetY) && detail.getHeight() >0 ) {
if (!detail.isPrintWhenExpressionNull()) {
detail.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
}
if (detail.isToPrint()) {
fillBlankRowBand(detail, JRExpression.EVALUATION_DEFAULT);
}
}
}
}
在JRHorizontalFiller类的fillReportEnd()函数和fillPageBreak()函数中,增加下
面这个函数的调用
private void fillBlankRowDetail() throws JRException {
if (log.isDebugEnabled() && !detail.isEmpty()) {
log.debug("Fill " + fillerId + ": detail");
}
if (!detail.isPrintWhenExpressionNull()) {
//calculator.estimateVariables();
detail.evaluatePrintWhenExpression(JRExpression.EVALUATION_ESTIMATED);
}
if (detail.isToPrint()) {
while ((columnIndex == columnCount - 1 ¦ ¦ isNewGroup)
&& detail.getHeight() <= columnFooterOffsetY - offsetY && detail.getHeight() >0) {
if (!detail.isPrintWhenExpressionNull()) {
detail.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT);
}
if (detail.isToPrint()) {
if (offsetX == lastDetailOffsetX
&& offsetY == lastDetailOffsetY) {
if (columnIndex == columnCount - 1) {
setFirstColumn();
}
else {
columnIndex++;
offsetX += columnWidth + columnSpacing;
offsetY -= detail.getHeight();
setColumnNumberVariable();
}
}
fillBlankRowBand(detail, JRExpression.EVALUATION_DEFAULT, false);
lastDetailOffsetX = offsetX;
lastDetailOffsetY = offsetY;
}
}
}
}
就搞定
JRVerticalFiller类的fillBlankRowBand函数
protected void fillBlankRowBand(JRFillBand band, byte evaluation) throws
JRException {
JRPrintBand printBand = band.fill(columnFooterOffsetY - offsetY -
band.getHeight());
java.util.List elements = printBand.getElements();
if (elements != null && elements.size() > 0) {
JRPrintElement element = null;
for (Iterator it = elements.iterator(); it.hasNext(); ) {
element = (JRPrintElement) it.next();
if(element instanceof JRPrintLine){
element.setX(element.getX() + offsetX);
element.setY(element.getY() + offsetY);
printPage.addElement(element);
}
}
}
offsetY += printBand.getHeight();
resolveBandBoundElements(band, evaluation);
}
JRHorizontalFiller类的fillBlankRowBand函数
protected void fillBlankRowBand(JRFillBand band, byte evaluation, boolean allowShrinking) throws JRException
{
//band.evaluate(evaluation);
JRPrintBand printBand = band.fill();
java.util.List elements = printBand.getElements();
if (elements != null && elements.size() > 0)
{
JRPrintElement element = null;
for(Iterator it = elements.iterator(); it.hasNext();)
{
if(element instanceof JRPrintLine){
element = (JRPrintElement) it.next();
element.setX(element.getX() + offsetX);
element.setY(element.getY() + offsetY);
printPage.addElement(element);
}
}
}
offsetY += allowShrinking ? printBand.getHeight() : band.getHeight();
resolveBandBoundElements(band, evaluation);
}