如何创建从 Java 调用的向下钻取报告?
How to create a drill-down report called from Java?
我已经使用 Jaspersoft Studio 创建了余额报告。我还在本报告中的一个字段上创建了具有以下属性的超链接:
Link Type: ReportExecution
Parameters: _report
上述参数的值为 "GLLedger",这是同一文件夹中存在的另一个 jasper 报告。
在 Java 中,当我调用此报告并单击超链接时,GLLedger 报告未出现但在控制台上出现以下警告:
Hyperlink of type ReportExecution
Implement your own JRHyperlinkListener to manage this type of event.
在 Java 中,我使用 JasperViewer 来预览报告。下面是代码:
JasperPrint jasperPrint = JasperFillManager.fillReport(reportPath, hm, connection);
JasperViewer v = new JasperViewer(jasperPrint, false);
v.setVisible(true);
能否指导如何从一个 jasper 报告中调用另一个报告?
如果您想在 swing 应用程序中使用它,您的主要问题(至少在 jasper 报告版本 <6.1.1 中)是您没有直接的方法来添加 JRHyperLinkListener
来自 JRViewer
的源代码:
//FIXME add a method to do addHyperlinkListener without subclassing
protected JRViewerPanel createViewerPanel(){return new JRViewerPanel(viewerContext);}
我将向您展示如何子class 这个 class,实现 JRHyperlinkListener
并使用从 link 收到的报告名称打开一个新框架.
Java代码
创建一个扩展 net.sf.jasperreports.swing.JRViewer
并实现 net.sf.jasperreports.view.JRHyperlinkListener
的 class,我正在添加导入,因为库具有同名的旧 classes,
import java.awt.BorderLayout;
import java.util.HashMap;
import javax.swing.JFrame;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRPrintHyperlink;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.swing.JRViewer;
import net.sf.jasperreports.swing.JRViewerPanel;
import net.sf.jasperreports.view.JRHyperlinkListener;
public class HyperLinkTest extends JRViewer implements JRHyperlinkListener {
private static final long serialVersionUID = -6429615130889276357L;
public HyperLinkTest(JasperPrint jrPrint){
super(jrPrint);
}
/**
* Since JRViewerPanel is protected our only way to add listener is
* to Override
*/
@Override
protected JRViewerPanel createViewerPanel()
{
JRViewerPanel panel = new JRViewerPanel(viewerContext);
panel.addHyperlinkListener(this);
return panel;
}
/**
* The listener gets the hyperlink reference and open relative report
*/
@Override
public void gotoHyperlink(JRPrintHyperlink arg) throws JRException {
JasperReport report = JasperCompileManager.compileReport("jasper/" + arg.getHyperlinkReference() + ".jrxml");
JasperPrint jasperPrint = JasperFillManager.fillReport(report, new HashMap<String, Object>());
HyperLinkTest nextReport = new HyperLinkTest(jasperPrint);
openReport("Navigated to", JFrame.DISPOSE_ON_CLOSE, nextReport);
}
/**
* static method that creates a frame and adds the JRViewer to it and
* open a new frame with the viewer
*/
public static void openReport(String title, int defaultCloseOperation, JRViewer hyperLinkReport){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame(title);
frame.setDefaultCloseOperation(defaultCloseOperation);
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(hyperLinkReport,BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
/**
* Main method to test
*/
public static void main(String[] args) throws JRException {
JasperReport report = JasperCompileManager.compileReport("jasper/hyperlink1.jrxml");
JasperPrint jasperPrint = JasperFillManager.fillReport(report, new HashMap<String, Object>());
HyperLinkTest test = new HyperLinkTest(jasperPrint);
openReport("Test hyperlink", JFrame.EXIT_ON_CLOSE, test);
}
}
Jrxml(报告)
从代码中可以看出,我正在使用 hyperlinkType="ReportExecution"
并在 hyperlinkReferenceExpression
中传递下一份报告的名称。
报告 1 (hyperlink1.jrxml)
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="hyperlink1" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="601103bc-66ab-45a5-8422-ccb6f3e02ec2">
<queryString>
<![CDATA[]]>
</queryString>
<title>
<band height="50">
<textField hyperlinkType="ReportExecution">
<reportElement x="0" y="0" width="100" height="20" uuid="8dc8f664-60b3-4b10-8a55-23120bea1f85"/>
<textElement>
<font size="14" isBold="true"/>
</textElement>
<textFieldExpression><![CDATA["Hello"]]></textFieldExpression>
<hyperlinkReferenceExpression><![CDATA["hyperlink2"]]></hyperlinkReferenceExpression>
</textField>
</band>
</title>
</jasperReport>
报告 2 (hyperlink2.jrxml)
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="hyperlink1" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="601103bc-66ab-45a5-8422-ccb6f3e02ec2">
<queryString>
<![CDATA[]]>
</queryString>
<title>
<band height="50">
<textField hyperlinkType="ReportExecution">
<reportElement x="113" y="0" width="100" height="20" uuid="8dc8f664-60b3-4b10-8a55-23120bea1f85"/>
<textElement>
<font size="14" isBold="true"/>
</textElement>
<textFieldExpression><![CDATA["World"]]></textFieldExpression>
<anchorNameExpression><![CDATA["World"]]></anchorNameExpression>
<hyperlinkReferenceExpression><![CDATA["hyperlink1"]]></hyperlinkReferenceExpression>
</textField>
</band>
</title>
</jasperReport>
结果
第一个 window 将以 "Hello" 打开,如果您单击 "Hello",第二个window 将以 "World"
打开
Notes: If I did this application probably I would pre-compile all .jrxml
to .jasper
, hence avoid compiling during run-time and probably I would have used multiple classes (1 for frame, 1 for viewer) avoiding static methods, however I have simplified to better fit SO format, concentrating on showing how a JRHyperLinkListener
can be implemented in a Swing application.
如何传递报表参数和其他数据
Can you please tell me how to pass connection Object and other parameters from first report to second from this
要将对象(字段、参数、变量或任何其他表达式)传递给 JRHyperlinkListener
,您应该 hyperlinkParameter
在 jrxml 中。
示例(参见 hyperlinkParameter
,它是 hyperlinkParameterExpression
)
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="hyperlink1" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="601103bc-66ab-45a5-8422-ccb6f3e02ec2">
<parameter name="reportDate" class="java.util.Date" isForPrompting="false">
<defaultValueExpression><![CDATA[new java.util.Date()]]></defaultValueExpression>
</parameter>
....
<textField hyperlinkType="ReportExecution">
<reportElement x="0" y="0" width="100" height="20" uuid="8dc8f664-60b3-4b10-8a55-23120bea1f85"/>
<textElement>
<font size="14" isBold="true"/>
</textElement>
<textFieldExpression><![CDATA["Hello"]]></textFieldExpression>
<hyperlinkReferenceExpression><![CDATA["hyperlink2"]]></hyperlinkReferenceExpression>
<hyperlinkParameter name="reportTime">
<hyperlinkParameterExpression><![CDATA[$P{reportDate}]]></hyperlinkParameterExpression>
</hyperlinkParameter>
</textField>
....
</jasperReport>
这个参数现在可以被JRHyperlinkListener
访问了,比如我把它传递给parameter map下次上报,自然jphlp.getValue()
会继续是instanceof java.util.Date
@Override
public void gotoHyperlink(JRPrintHyperlink arg) throws JRException {
Map<String, Object> nextReportParams = new HashMap<>();
List<JRPrintHyperlinkParameter> params = arg.getHyperlinkParameters().getParameters();
for (JRPrintHyperlinkParameter jphlp : params) {
if ("reportTime".equals(jphlp.getName())){
nextReportParams.put("previousReportTime",jphlp.getValue());
}
}
JasperReport report = JasperCompileManager.compileReport("jasper/" + arg.getHyperlinkReference() + ".jrxml");
JasperPrint jasperPrint = JasperFillManager.fillReport(report, nextReportParams);
HyperLinkTest nextReport = new HyperLinkTest(jasperPrint);
openReport("Navigated to", JFrame.DISPOSE_ON_CLOSE, nextReport);
}
Notes: Watch out passing main report datasource (this will be at the
end, you cannot re-use it, if you do not rewind it first) and
connection (this may be closed), it's better to pass a new connection to next report.
我已经使用 Jaspersoft Studio 创建了余额报告。我还在本报告中的一个字段上创建了具有以下属性的超链接:
Link Type: ReportExecution
Parameters: _report
上述参数的值为 "GLLedger",这是同一文件夹中存在的另一个 jasper 报告。
在 Java 中,当我调用此报告并单击超链接时,GLLedger 报告未出现但在控制台上出现以下警告:
Hyperlink of type ReportExecution
Implement your own JRHyperlinkListener to manage this type of event.
在 Java 中,我使用 JasperViewer 来预览报告。下面是代码:
JasperPrint jasperPrint = JasperFillManager.fillReport(reportPath, hm, connection);
JasperViewer v = new JasperViewer(jasperPrint, false);
v.setVisible(true);
能否指导如何从一个 jasper 报告中调用另一个报告?
如果您想在 swing 应用程序中使用它,您的主要问题(至少在 jasper 报告版本 <6.1.1 中)是您没有直接的方法来添加 JRHyperLinkListener
来自 JRViewer
的源代码:
//FIXME add a method to do addHyperlinkListener without subclassing
protected JRViewerPanel createViewerPanel(){return new JRViewerPanel(viewerContext);}
我将向您展示如何子class 这个 class,实现 JRHyperlinkListener
并使用从 link 收到的报告名称打开一个新框架.
Java代码
创建一个扩展 net.sf.jasperreports.swing.JRViewer
并实现 net.sf.jasperreports.view.JRHyperlinkListener
的 class,我正在添加导入,因为库具有同名的旧 classes,
import java.awt.BorderLayout;
import java.util.HashMap;
import javax.swing.JFrame;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRPrintHyperlink;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.swing.JRViewer;
import net.sf.jasperreports.swing.JRViewerPanel;
import net.sf.jasperreports.view.JRHyperlinkListener;
public class HyperLinkTest extends JRViewer implements JRHyperlinkListener {
private static final long serialVersionUID = -6429615130889276357L;
public HyperLinkTest(JasperPrint jrPrint){
super(jrPrint);
}
/**
* Since JRViewerPanel is protected our only way to add listener is
* to Override
*/
@Override
protected JRViewerPanel createViewerPanel()
{
JRViewerPanel panel = new JRViewerPanel(viewerContext);
panel.addHyperlinkListener(this);
return panel;
}
/**
* The listener gets the hyperlink reference and open relative report
*/
@Override
public void gotoHyperlink(JRPrintHyperlink arg) throws JRException {
JasperReport report = JasperCompileManager.compileReport("jasper/" + arg.getHyperlinkReference() + ".jrxml");
JasperPrint jasperPrint = JasperFillManager.fillReport(report, new HashMap<String, Object>());
HyperLinkTest nextReport = new HyperLinkTest(jasperPrint);
openReport("Navigated to", JFrame.DISPOSE_ON_CLOSE, nextReport);
}
/**
* static method that creates a frame and adds the JRViewer to it and
* open a new frame with the viewer
*/
public static void openReport(String title, int defaultCloseOperation, JRViewer hyperLinkReport){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame(title);
frame.setDefaultCloseOperation(defaultCloseOperation);
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(hyperLinkReport,BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
/**
* Main method to test
*/
public static void main(String[] args) throws JRException {
JasperReport report = JasperCompileManager.compileReport("jasper/hyperlink1.jrxml");
JasperPrint jasperPrint = JasperFillManager.fillReport(report, new HashMap<String, Object>());
HyperLinkTest test = new HyperLinkTest(jasperPrint);
openReport("Test hyperlink", JFrame.EXIT_ON_CLOSE, test);
}
}
Jrxml(报告)
从代码中可以看出,我正在使用 hyperlinkType="ReportExecution"
并在 hyperlinkReferenceExpression
中传递下一份报告的名称。
报告 1 (hyperlink1.jrxml)
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="hyperlink1" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="601103bc-66ab-45a5-8422-ccb6f3e02ec2">
<queryString>
<![CDATA[]]>
</queryString>
<title>
<band height="50">
<textField hyperlinkType="ReportExecution">
<reportElement x="0" y="0" width="100" height="20" uuid="8dc8f664-60b3-4b10-8a55-23120bea1f85"/>
<textElement>
<font size="14" isBold="true"/>
</textElement>
<textFieldExpression><![CDATA["Hello"]]></textFieldExpression>
<hyperlinkReferenceExpression><![CDATA["hyperlink2"]]></hyperlinkReferenceExpression>
</textField>
</band>
</title>
</jasperReport>
报告 2 (hyperlink2.jrxml)
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="hyperlink1" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="601103bc-66ab-45a5-8422-ccb6f3e02ec2">
<queryString>
<![CDATA[]]>
</queryString>
<title>
<band height="50">
<textField hyperlinkType="ReportExecution">
<reportElement x="113" y="0" width="100" height="20" uuid="8dc8f664-60b3-4b10-8a55-23120bea1f85"/>
<textElement>
<font size="14" isBold="true"/>
</textElement>
<textFieldExpression><![CDATA["World"]]></textFieldExpression>
<anchorNameExpression><![CDATA["World"]]></anchorNameExpression>
<hyperlinkReferenceExpression><![CDATA["hyperlink1"]]></hyperlinkReferenceExpression>
</textField>
</band>
</title>
</jasperReport>
结果
第一个 window 将以 "Hello" 打开,如果您单击 "Hello",第二个window 将以 "World"
打开Notes: If I did this application probably I would pre-compile all
.jrxml
to.jasper
, hence avoid compiling during run-time and probably I would have used multiple classes (1 for frame, 1 for viewer) avoiding static methods, however I have simplified to better fit SO format, concentrating on showing how aJRHyperLinkListener
can be implemented in a Swing application.
如何传递报表参数和其他数据
Can you please tell me how to pass connection Object and other parameters from first report to second from this
要将对象(字段、参数、变量或任何其他表达式)传递给 JRHyperlinkListener
,您应该 hyperlinkParameter
在 jrxml 中。
示例(参见 hyperlinkParameter
,它是 hyperlinkParameterExpression
)
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="hyperlink1" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="601103bc-66ab-45a5-8422-ccb6f3e02ec2">
<parameter name="reportDate" class="java.util.Date" isForPrompting="false">
<defaultValueExpression><![CDATA[new java.util.Date()]]></defaultValueExpression>
</parameter>
....
<textField hyperlinkType="ReportExecution">
<reportElement x="0" y="0" width="100" height="20" uuid="8dc8f664-60b3-4b10-8a55-23120bea1f85"/>
<textElement>
<font size="14" isBold="true"/>
</textElement>
<textFieldExpression><![CDATA["Hello"]]></textFieldExpression>
<hyperlinkReferenceExpression><![CDATA["hyperlink2"]]></hyperlinkReferenceExpression>
<hyperlinkParameter name="reportTime">
<hyperlinkParameterExpression><![CDATA[$P{reportDate}]]></hyperlinkParameterExpression>
</hyperlinkParameter>
</textField>
....
</jasperReport>
这个参数现在可以被JRHyperlinkListener
访问了,比如我把它传递给parameter map下次上报,自然jphlp.getValue()
会继续是instanceof java.util.Date
@Override
public void gotoHyperlink(JRPrintHyperlink arg) throws JRException {
Map<String, Object> nextReportParams = new HashMap<>();
List<JRPrintHyperlinkParameter> params = arg.getHyperlinkParameters().getParameters();
for (JRPrintHyperlinkParameter jphlp : params) {
if ("reportTime".equals(jphlp.getName())){
nextReportParams.put("previousReportTime",jphlp.getValue());
}
}
JasperReport report = JasperCompileManager.compileReport("jasper/" + arg.getHyperlinkReference() + ".jrxml");
JasperPrint jasperPrint = JasperFillManager.fillReport(report, nextReportParams);
HyperLinkTest nextReport = new HyperLinkTest(jasperPrint);
openReport("Navigated to", JFrame.DISPOSE_ON_CLOSE, nextReport);
}
Notes: Watch out passing main report datasource (this will be at the end, you cannot re-use it, if you do not rewind it first) and connection (this may be closed), it's better to pass a new connection to next report.