Jasper reports 使用iReport 5.1.0设计的JasperReport PDF中的边界构件

Jasper reports 使用iReport 5.1.0设计的JasperReport PDF中的边界构件,jasper-reports,ireport,Jasper Reports,Ireport,在使用JasperReports生成报告时,我看到报告引擎绘制了奇怪的边界。有时会绘制边框,使线条以100%的缩放级别突出,如图所示。这意味着,当我试图绘制一个正方形文本框时,它将不会看起来像一个正方形,除非我放大到150%以获得更多。这是一张显示问题的图片 在iReport中设置边框设置时是否出错?我如何解决这个问题?我也有同样的问题。将表格导出为PDF格式并使用薄表格边框时,单元格边框线似乎超出表格边框一个像素。视觉构件仅在某些PDF查看器中可见(在Adobe Reader中可见),并且仅

在使用JasperReports生成报告时,我看到报告引擎绘制了奇怪的边界。有时会绘制边框,使线条以100%的缩放级别突出,如图所示。这意味着,当我试图绘制一个正方形文本框时,它将不会看起来像一个正方形,除非我放大到150%以获得更多。这是一张显示问题的图片


在iReport中设置边框设置时是否出错?我如何解决这个问题?

我也有同样的问题。将表格导出为PDF格式并使用薄表格边框时,单元格边框线似乎超出表格边框一个像素。视觉构件仅在某些PDF查看器中可见(在Adobe Reader中可见),并且仅在某些缩放级别上可见。在PDF viewer中打开或关闭线条艺术平滑时,瑕疵的外观会发生变化。如果在最大级别放大overstrike,则可以看到线条绘制正确-在缩放文档时,PDF查看器会生成瑕疵

在检查JasperReports代码时,我发现PDF导出将表格边框绘制为四行。绘制时不带封口(线在末端立即切断)。以这种方式绘制方形边框时,角点不会完全连接,因此每条线的绘制长度略大于边框,以补偿缺少的封口。对我来说,这个算法似乎是正确的,但是Adobe Reader中发生了一些事情,一些舍入和图像“改进”导致图像瑕疵出现

在我的案例中,我能够想出一个解决方案来解决这个问题。我已经对JRPdfExporter进行了子类化,并修改了绘制边框的代码。用法很简单,只需使用my类而不是JRPdfExporter。我使用JasperReports 5.0.0

package cz.jwa.jasper;

import java.awt.Color;

import net.sf.jasperreports.engine.JRLineBox;
import net.sf.jasperreports.engine.JRPen;
import net.sf.jasperreports.engine.JRPrintElement;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.legacy.BorderOffset;
import net.sf.jasperreports.engine.type.LineStyleEnum;

import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfContentByte;

public class JWAPdfExporter extends JRPdfExporter
{
  protected void exportBox(JRLineBox box, JRPrintElement element)
  {
    if(!isBoxVisible(box)) return;

    pdfContentByte.setLineCap(PdfContentByte.LINE_CAP_PROJECTING_SQUARE);    

    float x1 = element.getX() + getOffsetX();
    float y1 = jasperPrint.getPageHeight() - element.getY() - getOffsetY();
    float x2 = element.getX() + getOffsetX() + element.getWidth();
    float y2 = jasperPrint.getPageHeight() - element.getY() - getOffsetY() - element.getHeight(); 

    Rectangle r = new Rectangle(x1, y2, x2, y1);

    int borderFlag = 0;

    boolean same = true;

    float lineWidth = 0;
    Color lineColor = null;

    if(box.getLeftPen().getLineWidth().floatValue() > 0f)
    {
      borderFlag |= Rectangle.LEFT;
      lineWidth = box.getLeftPen().getLineWidth().floatValue();
      lineColor = box.getLeftPen().getLineColor(); 
    }

    if(box.getTopPen().getLineWidth().floatValue() > 0f)
    {
      borderFlag |= Rectangle.TOP;
      if(lineWidth == 0)
      {
        lineWidth = box.getTopPen().getLineWidth().floatValue();
        lineColor = box.getTopPen().getLineColor(); 
      }
      else if(lineWidth != box.getTopPen().getLineWidth().floatValue()
          || !lineColor.equals(box.getTopPen().getLineColor()))
      {
        same = false;
      }
    }

    if(box.getRightPen().getLineWidth().floatValue() > 0f)
    {
      borderFlag |= Rectangle.RIGHT;
      if(lineWidth == 0)
      {
        lineWidth = box.getRightPen().getLineWidth().floatValue();
        lineColor = box.getRightPen().getLineColor(); 
      }
      else if(lineWidth != box.getRightPen().getLineWidth().floatValue()
          || !lineColor.equals(box.getRightPen().getLineColor()))
      {
        same = false;
      }
    }

    if(box.getBottomPen().getLineWidth().floatValue() > 0f)
    {
      borderFlag |= Rectangle.BOTTOM;
      if(lineWidth == 0)
      {
        lineWidth = box.getBottomPen().getLineWidth().floatValue();
        lineColor = box.getBottomPen().getLineColor(); 
      }
      else if(lineWidth != box.getBottomPen().getLineWidth().floatValue()
          || !lineColor.equals(box.getBottomPen().getLineColor()))
      {
        same = false;
      }
    }

    if(same)
    {
      r.setBorder(borderFlag);
      r.setBorderColor(lineColor);
      r.setBorderWidth(lineWidth);

      pdfContentByte.rectangle(r);
      pdfContentByte.stroke();

      pdfContentByte.setLineDash(0.0F);
      pdfContentByte.setLineCap(PdfContentByte.LINE_CAP_PROJECTING_SQUARE);   
    }
    else
    {
      super.exportBox(box, element);
    }    
  }

  private boolean isBoxVisible(JRLineBox box)
  {
    return box.getLeftPen().getLineWidth().floatValue() > 0f 
        || box.getTopPen().getLineWidth().floatValue() > 0f
        || box.getRightPen().getLineWidth().floatValue() > 0f
        || box.getBottomPen().getLineWidth().floatValue() > 0f
        ;
  }

  protected void exportTopPen(
      JRPen topPen, 
      JRPen leftPen, 
      JRPen rightPen, 
      JRPrintElement element)
    {
      if (topPen.getLineWidth().floatValue() > 0f)
      {
        float leftOffset = 0; //leftPen.getLineWidth().floatValue() / 2 - BorderOffset.getOffset(leftPen);
        float rightOffset = 0; //rightPen.getLineWidth().floatValue() / 2 - BorderOffset.getOffset(rightPen);

        preparePen(pdfContentByte, topPen, PdfContentByte.LINE_CAP_BUTT);

        if (topPen.getLineStyleValue() == LineStyleEnum.DOUBLE)
        {
          float topOffset = topPen.getLineWidth().floatValue();

          pdfContentByte.moveTo(
            element.getX() + getOffsetX() - leftOffset,
            jasperPrint.getPageHeight() - element.getY() - getOffsetY() + topOffset / 3
            );
          pdfContentByte.lineTo(
            element.getX() + getOffsetX() + element.getWidth() + rightOffset,
            jasperPrint.getPageHeight() - element.getY() - getOffsetY() + topOffset / 3
            );
          pdfContentByte.stroke();

          pdfContentByte.moveTo(
            element.getX() + getOffsetX() + leftOffset / 3,
            jasperPrint.getPageHeight() - element.getY() - getOffsetY() - topOffset / 3
            );
          pdfContentByte.lineTo(
            element.getX() + getOffsetX() + element.getWidth() - rightOffset / 3,
            jasperPrint.getPageHeight() - element.getY() - getOffsetY() - topOffset / 3
            );
          pdfContentByte.stroke();
        }
        else
        {
          float topOffset =  BorderOffset.getOffset(topPen);
          pdfContentByte.moveTo(
            element.getX() + getOffsetX() - leftOffset,
            jasperPrint.getPageHeight() - element.getY() - getOffsetY() - topOffset
            );
          pdfContentByte.lineTo(
            element.getX() + getOffsetX() + element.getWidth() + rightOffset,
            jasperPrint.getPageHeight() - element.getY() - getOffsetY() - topOffset
            );
          pdfContentByte.stroke();
        }
      }
    }

  protected void exportLeftPen(JRPen topPen, JRPen leftPen, JRPen bottomPen, JRPrintElement element)
  {
    if (leftPen.getLineWidth().floatValue() > 0f)
    {
      float topOffset = 0; //topPen.getLineWidth().floatValue() / 2 - BorderOffset.getOffset(topPen);
      float bottomOffset = 0; //bottomPen.getLineWidth().floatValue() / 2 - BorderOffset.getOffset(bottomPen);

      preparePen(pdfContentByte, leftPen, PdfContentByte.LINE_CAP_BUTT);

      if (leftPen.getLineStyleValue() == LineStyleEnum.DOUBLE)
      {
        float leftOffset = leftPen.getLineWidth().floatValue();

        pdfContentByte.moveTo(
          element.getX() + getOffsetX() - leftOffset / 3,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() + topOffset
          );
        pdfContentByte.lineTo(
          element.getX() + getOffsetX() - leftOffset / 3,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() - element.getHeight() - bottomOffset
          );
        pdfContentByte.stroke();

        pdfContentByte.moveTo(
          element.getX() + getOffsetX() + leftOffset / 3,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() - topOffset / 3
          );
        pdfContentByte.lineTo(
          element.getX() + getOffsetX() + leftOffset / 3,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() - element.getHeight() + bottomOffset / 3
          );
        pdfContentByte.stroke();
      }
      else
      {
        float leftOffset =  BorderOffset.getOffset(leftPen);
        pdfContentByte.moveTo(
          element.getX() + getOffsetX() + leftOffset,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() + topOffset
          );
        pdfContentByte.lineTo(
          element.getX() + getOffsetX() + leftOffset,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() - element.getHeight() - bottomOffset
          );
        pdfContentByte.stroke();
      }
    }
  }


  /**
   *
   */
  protected void exportBottomPen(JRPen leftPen, JRPen bottomPen, JRPen rightPen, JRPrintElement element)
  {
    if (bottomPen.getLineWidth().floatValue() > 0f)
    {
      float leftOffset = 0; //leftPen.getLineWidth().floatValue() / 2 - BorderOffset.getOffset(leftPen);
      float rightOffset = 0; //rightPen.getLineWidth().floatValue() / 2 - BorderOffset.getOffset(rightPen);

      preparePen(pdfContentByte, bottomPen, PdfContentByte.LINE_CAP_BUTT);

      if (bottomPen.getLineStyleValue() == LineStyleEnum.DOUBLE)
      {
        float bottomOffset = bottomPen.getLineWidth().floatValue();

        pdfContentByte.moveTo(
          element.getX() + getOffsetX() - leftOffset,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() - element.getHeight() - bottomOffset / 3
          );
        pdfContentByte.lineTo(
          element.getX() + getOffsetX() + element.getWidth() + rightOffset,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() - element.getHeight() - bottomOffset / 3
          );
        pdfContentByte.stroke();

        pdfContentByte.moveTo(
          element.getX() + getOffsetX() + leftOffset / 3,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() - element.getHeight() + bottomOffset / 3
          );
        pdfContentByte.lineTo(
          element.getX() + getOffsetX() + element.getWidth() - rightOffset / 3,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() - element.getHeight() + bottomOffset / 3
          );
        pdfContentByte.stroke();
      }
      else
      {
        float bottomOffset =  BorderOffset.getOffset(bottomPen);
        pdfContentByte.moveTo(
          element.getX() + getOffsetX() - leftOffset,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() - element.getHeight() + bottomOffset
          );
        pdfContentByte.lineTo(
          element.getX() + getOffsetX() + element.getWidth() + rightOffset,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() - element.getHeight() + bottomOffset
          );
        pdfContentByte.stroke();
      }
    }
  }


  /**
   *
   */
  protected void exportRightPen(JRPen topPen, JRPen bottomPen, JRPen rightPen, JRPrintElement element)
  {
    if (rightPen.getLineWidth().floatValue() > 0f)
    {
      float topOffset = 0; //topPen.getLineWidth().floatValue() / 2 - BorderOffset.getOffset(topPen);
      float bottomOffset = 0; //bottomPen.getLineWidth().floatValue() / 2 - BorderOffset.getOffset(bottomPen);

      preparePen(pdfContentByte, rightPen, PdfContentByte.LINE_CAP_BUTT);

      if (rightPen.getLineStyleValue() == LineStyleEnum.DOUBLE)
      {
        float rightOffset = rightPen.getLineWidth().floatValue();

        pdfContentByte.moveTo(
          element.getX() + getOffsetX() + element.getWidth() + rightOffset / 3,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() + topOffset
          );
        pdfContentByte.lineTo(
          element.getX() + getOffsetX() + element.getWidth() + rightOffset / 3,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() - element.getHeight() - bottomOffset
          );
        pdfContentByte.stroke();

        pdfContentByte.moveTo(
          element.getX() + getOffsetX() + element.getWidth() - rightOffset / 3,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() - topOffset / 3
          );
        pdfContentByte.lineTo(
          element.getX() + getOffsetX() + element.getWidth() - rightOffset / 3,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() - element.getHeight() + bottomOffset / 3
          );
        pdfContentByte.stroke();
      }
      else
      {
        float rightOffset =  BorderOffset.getOffset(rightPen);
        pdfContentByte.moveTo(
          element.getX() + getOffsetX() + element.getWidth() - rightOffset,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() + topOffset
          );
        pdfContentByte.lineTo(
          element.getX() + getOffsetX() + element.getWidth() - rightOffset,
          jasperPrint.getPageHeight() - element.getY() - getOffsetY() - element.getHeight() - bottomOffset
          );
        pdfContentByte.stroke();
      }
    }
  }

  private static void preparePen(PdfContentByte pdfContentByte, JRPen pen, int lineCap)
  {
    float lineWidth = pen.getLineWidth().floatValue();

    if (lineWidth <= 0)
    {
      return;
    }

    pdfContentByte.setLineWidth(lineWidth);
    pdfContentByte.setLineCap(lineCap);

    Color color = pen.getLineColor();
    pdfContentByte.setRGBColorStroke(color.getRed(), color.getGreen(), color.getBlue());

    switch (pen.getLineStyleValue())
    {
      case DOUBLE:
      {
        pdfContentByte.setLineWidth(lineWidth / 3);
        pdfContentByte.setLineDash(0f);
        break;
      }
      case DOTTED:
      {
        switch (lineCap)
        {
          case PdfContentByte.LINE_CAP_BUTT:
          {
            pdfContentByte.setLineDash(lineWidth, lineWidth, 0f);
            break;
          }
          case PdfContentByte.LINE_CAP_PROJECTING_SQUARE:
          {
            pdfContentByte.setLineDash(0, 2 * lineWidth, 0f);
            break;
          }
        }
        break;
      }
      case DASHED:
      {
        switch (lineCap)
        {
          case PdfContentByte.LINE_CAP_BUTT:
          {
            pdfContentByte.setLineDash(5 * lineWidth, 3 * lineWidth, 0f);
            break;
          }
          case PdfContentByte.LINE_CAP_PROJECTING_SQUARE:
          {
            pdfContentByte.setLineDash(4 * lineWidth, 4 * lineWidth, 0f);
            break;
          }
        }
        break;
      }
      case SOLID:
      default:
      {
        pdfContentByte.setLineDash(0f);
        break;
      }
    }
  }
}
包cz.jwa.jasper;
导入java.awt.Color;
导入net.sf.jasperreports.engine.JRLineBox;
导入net.sf.jasperreports.engine.JRPen;
导入net.sf.jasperreports.engine.JRPrintElement;
导入net.sf.jasperreports.engine.export.JRPdfExporter;
导入net.sf.jasperreports.engine.export.legacy.BorderOffset;
导入net.sf.jasperreports.engine.type.LineStyleEnum;
导入com.lowagie.text.Rectangle;
导入com.lowagie.text.pdf.PdfContentByte;
公共类JWAPdfExporter扩展了JRPdfExporter
{
受保护的void导出框(JRLineBox框、JRPrintElement元素)
{
如果(!isBoxVisible(box))返回;
pdfContentByte.setLineCap(pdfContentByte.LINE\u CAP\u PROJECTING\u SQUARE);
float x1=element.getX()+getOffsetX();
float y1=jasperPrint.getPageHeight()-element.getY()-getOffsetY();
float x2=element.getX()+getOffsetX()+element.getWidth();
float y2=jasperPrint.getPageHeight()-element.getY()-getOffsetY()-element.getHeight();
矩形r=新矩形(x1,y2,x2,y1);
int borderFlag=0;
布尔值相同=真;
浮动线宽=0;
Color lineColor=null;
如果(box.getLeftPen().getLineWidth().floatValue()>0f)
{
borderFlag |=矩形。左;
lineWidth=box.getLeftPen().getLineWidth().floatValue();
lineColor=box.getLeftPen().getLineColor();
}
if(box.getTopPen().getLineWidth().floatValue()>0f)
{
borderFlag |=Rectangle.TOP;
如果(线宽==0)
{
lineWidth=box.getTopPen().getLineWidth().floatValue();
lineColor=box.getTopPen().getLineColor();
}
else if(线宽!=box.getTopPen().getLineWidth().floatValue()
||!lineColor.equals(box.getTopPen().getLineColor())
{
相同=错误;
}
}
如果(box.getRightPen().getLineWidth().floatValue()>0f)
{
borderFlag |=矩形。右;
如果(线宽==0)
{
线宽=box.getRightPen().getLineWidth().floatValue();
lineColor=box.getRightPen().getLineColor();
}
else if(线宽!=box.getRightPen().getLineWidth().floatValue())
||!lineColor.equals(box.getRightPen().getLineColor())
{
相同=错误;
}
}
如果(box.getBottomPen().getLineWidth().floatValue()>0f)
{
borderFlag |=矩形。底部;
如果(线宽==0)
{
lineWidth=box.getBottomPen().getLineWidth().floatValue();
lineColor=box.getBottomPen().getLineColor();
}
else if(线宽!=box.getBottomPen().getLineWidth().floatValue()
||!lineColor.equals(box.getBottomPen().getLineColor())
{
相同=错误;
}
}
如果(相同)
{
r、 订单(边界标志);
r、 颜色(线条颜色);
r、 线条宽度(线宽);
pdfContentByte.矩形(r);
pdfContentByte.stroke();
pdfContentByte.setLineDash(0.0F);
pdfContentByte.setLineCap(pdfContentByte.LINE\u CAP\u PROJECTING\u SQUARE);
}
其他的
{
super.exportBox(框、元素);
}    
}
私有布尔值isBoxVisible(JRLineBox)
{
返回框.getLeftPen().getLineWidth().floatValue()>0f
||box.getTopPen().getLineWidth().floatValue()>0f
||box.getRightPen().getLineWidth().floatValue()>0f
||box.getBottomPen().getLineWidth().floatValue()>0f
;
}
受保护的无效输出端(
杰彭·托彭,
JRPen leftPen,
JRPen rightPen,
JRPrintElement(打印元素)
{
如果(topPen.getLineWidth().floatValue()>0f)
{
float leftOffset=0;//leftPen.getLineWidth().floatValue()/2-BorderOffset.getOffset(leftPen);
float rightOffset=0;//rightPen.getLineWidth().floatValue()/2-BorderOffset.getOffset(rightPen);
preparePen(pdfContentByte、topPen、pdfContentByte.LINE\u CAP\u BUTT);
if(topPen.getLineStyleValue()==LineStyleEnum.DOUBLE)
{
float topOffset=topPen.getLineWidth().floatValue();
pdfContentByte.moveTo(
element.getX()+getOffsetX()-leftOffset,
jasperPrint.getPageHeight()-element.getY()-ge