【问题标题】:How to add a json array to a table using java so that I can pass cookies?如何使用 java 将 json 数组添加到表中以便我可以传递 cookie?
【发布时间】:2017-06-05 04:22:12
【问题描述】:

我有这样的 json 对象

{
  "data":[
    {
       "no":1,
       "name" : "yuda",
       "address" : "surabaya"
    },
    {
        "no":2,
        "name":"adi",
        "address":"jakarta"
    }
  ],
  "comp_name":"TEST CORP",
  "title":"Company employee",
  "status":"success"
}

我使用 http rest API 为该 json 提供服务,我想使用 jasper 报告创建报告,如果我将其作为 url JsonQueryExecuterFactory.JSON_SOURCE 传递,我将成功。

我的问题是我不能在JSON_SOURCE 中包含会话cookie,我正在尝试的解决方案是在java 代码中创建一个http 请求,然后将它包含在JsonQueryExecuterFactory.JSON_INPUT_STREAM 中,但它不起作用,它只是显示空白页。即使我将参数从$P{net.sf.jasperreports.json.source} 更新为$P{JSON_INPUT_STREAM},它也不起作用。

【问题讨论】:

  • 你试过这样的事情吗? stackoverflow.com/a/36455240/5292302,不清楚你目前是如何尝试传递数据源的,尝试创建一个minimal reproducible example
  • @PetterFriberg 我已经阅读了你对那个问题的回答,如果 json 只是标准 json 对象,它就可以工作,在我的情况下,“data”键中有 json 数组,我需要把 json表格内的数组。
  • 好的,看看如何从主数据源stackoverflow.com/a/39401536/5292302为您的表创建subDataSource
  • 如果您没有绑定到特定版本的 JasperReports,您的所有问题都可以使用最新(6.3.1)版本轻松解决:使用header properties,您可以为您的 URL 设置一个 cookie 标头;使用JSONQL,您可以访问嵌套的 JSON 数组,而无需创建额外的数据集。
  • @Narcis 请给我一些关于header properties的例子,我不知道怎么用。

标签: java json jasper-reports


【解决方案1】:

这是通过 java 从 http 请求加载 json 的完整示例(您可以根据需要添加标头),使用子报告将 data 节点作为 subDataSource 传递

示例网址: http://www.jdd.it/so/jsonTest.json *您的 json 在此网址上可用

主报告(jsonMain.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="JsonMain" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="15289120-bdf0-4edd-905c-647999c3c0cc">
    <property name="com.jaspersoft.studio.data.defaultdataadapter" value="json"/>
    <parameter name="SUBREPORT_DIR" class="java.lang.String" isForPrompting="false">
        <defaultValueExpression><![CDATA["C:\\jdd\\..path..to..subreport\\"]]></defaultValueExpression>
    </parameter>
    <queryString language="JSON">
        <![CDATA[]]>
    </queryString>
    <field name="comp_name" class="java.lang.String">
        <fieldDescription><![CDATA[comp_name]]></fieldDescription>
    </field>
    <field name="title" class="java.lang.String">
        <fieldDescription><![CDATA[title]]></fieldDescription>
    </field>
    <field name="status" class="java.lang.String">
        <fieldDescription><![CDATA[status]]></fieldDescription>
    </field>
    <detail>
        <band height="40">
            <staticText>
                <reportElement x="0" y="0" width="115" height="20" uuid="023be3f7-66fc-4718-9ca3-220c16ddc97a"/>
                <textElement verticalAlignment="Middle">
                    <font size="14" isBold="true"/>
                </textElement>
                <text><![CDATA[Company name:]]></text>
            </staticText>
            <textField>
                <reportElement x="115" y="0" width="103" height="20" uuid="15aadf03-03a1-4c05-8bf9-cdf7db09153c"/>
                <textElement verticalAlignment="Middle">
                    <font size="14" isBold="true"/>
                </textElement>
                <textFieldExpression><![CDATA[$F{comp_name}]]></textFieldExpression>
            </textField>
            <subreport>
                <reportElement x="0" y="20" width="555" height="20" uuid="c8251ce1-5de4-476f-a4cc-89717d422cc7"/>
                <dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("data")]]></dataSourceExpression>
                <subreportExpression><![CDATA[$P{SUBREPORT_DIR} + "jsonMain_subreport.jasper"]]></subreportExpression>
            </subreport>
            <staticText>
                <reportElement x="218" y="0" width="39" height="20" uuid="4c8d8333-117a-4447-98ac-bfebbd28776a"/>
                <textElement verticalAlignment="Middle">
                    <font size="14" isBold="true"/>
                </textElement>
                <text><![CDATA[Title:]]></text>
            </staticText>
            <textField>
                <reportElement x="257" y="0" width="154" height="20" uuid="0f266993-1bf3-41cf-8db6-c8b5aaccef74"/>
                <textElement verticalAlignment="Middle">
                    <font size="14" isBold="true"/>
                </textElement>
                <textFieldExpression><![CDATA[$F{title}]]></textFieldExpression>
            </textField>
            <staticText>
                <reportElement x="411" y="0" width="51" height="20" uuid="9afd4de9-5155-43a6-ae63-337bb77deac8"/>
                <textElement verticalAlignment="Middle">
                    <font size="14" isBold="true"/>
                </textElement>
                <text><![CDATA[Status:]]></text>
            </staticText>
            <textField>
                <reportElement x="462" y="0" width="93" height="20" uuid="6e8ab3b0-c8eb-40f4-ade8-9dd60e34a721"/>
                <textElement verticalAlignment="Middle">
                    <font size="14" isBold="true"/>
                </textElement>
                <textFieldExpression><![CDATA[$F{status}]]></textFieldExpression>
            </textField>
        </band>
    </detail>
</jasperReport>

关键是subDataSourcedata节点((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("data") 并将其传递给子报表

子报表(jsonMain_subreport.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="jsonMain_subreport" language="java" pageWidth="555" pageHeight="802" columnWidth="555" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0" uuid="9c681432-4547-4fd8-91c1-5634ca368da6">
    <field name="no" class="java.lang.String"/>
    <field name="name" class="java.lang.String"/>
    <field name="address" class="java.lang.String"/>
    <columnHeader>
        <band height="20" splitType="Stretch">
            <staticText>
                <reportElement mode="Opaque" x="0" y="0" width="100" height="20" backcolor="#CCCCCC" uuid="3dbc394e-6a5a-45d2-8d53-c9880f3974e7"/>
                <box leftPadding="2" rightPadding="2">
                    <pen lineWidth="0.25"/>
                    <topPen lineWidth="0.25"/>
                    <leftPen lineWidth="0.25"/>
                    <bottomPen lineWidth="0.25"/>
                    <rightPen lineWidth="0.25"/>
                </box>
                <textElement verticalAlignment="Middle"/>
                <text><![CDATA[No]]></text>
            </staticText>
            <staticText>
                <reportElement mode="Opaque" x="100" y="0" width="167" height="20" backcolor="#CCCCCC" uuid="2c40967a-42d5-439e-a1c3-5d41fd50f906"/>
                <box leftPadding="2" rightPadding="2">
                    <pen lineWidth="0.25"/>
                    <topPen lineWidth="0.25"/>
                    <leftPen lineWidth="0.25"/>
                    <bottomPen lineWidth="0.25"/>
                    <rightPen lineWidth="0.25"/>
                </box>
                <textElement verticalAlignment="Middle"/>
                <text><![CDATA[Name]]></text>
            </staticText>
            <staticText>
                <reportElement mode="Opaque" x="267" y="0" width="288" height="20" backcolor="#CCCCCC" uuid="0d72063d-6354-4e8d-9f89-52d00d100d3e"/>
                <box leftPadding="2" rightPadding="2">
                    <pen lineWidth="0.25"/>
                    <topPen lineWidth="0.25"/>
                    <leftPen lineWidth="0.25"/>
                    <bottomPen lineWidth="0.25"/>
                    <rightPen lineWidth="0.25"/>
                </box>
                <textElement verticalAlignment="Middle"/>
                <text><![CDATA[Address]]></text>
            </staticText>
        </band>
    </columnHeader>
    <detail>
        <band height="20" splitType="Stretch">
            <textField>
                <reportElement x="0" y="0" width="100" height="20" uuid="e9cc4829-5e9a-4747-a594-489b6230713c"/>
                <box leftPadding="2" rightPadding="2">
                    <pen lineWidth="0.25"/>
                    <topPen lineWidth="0.25"/>
                    <leftPen lineWidth="0.25"/>
                    <bottomPen lineWidth="0.25"/>
                    <rightPen lineWidth="0.25"/>
                </box>
                <textElement verticalAlignment="Middle"/>
                <textFieldExpression><![CDATA[$F{no}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="100" y="0" width="167" height="20" uuid="1c02f144-1c6c-4704-9bfb-13ac39007841"/>
                <box leftPadding="2" rightPadding="2">
                    <pen lineWidth="0.25"/>
                    <topPen lineWidth="0.25"/>
                    <leftPen lineWidth="0.25"/>
                    <bottomPen lineWidth="0.25"/>
                    <rightPen lineWidth="0.25"/>
                </box>
                <textElement verticalAlignment="Middle"/>
                <textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="267" y="0" width="288" height="20" uuid="e0b9aff3-c8e3-4895-90a2-339ffb7c856f"/>
                <box leftPadding="2" rightPadding="2">
                    <pen lineWidth="0.25"/>
                    <topPen lineWidth="0.25"/>
                    <leftPen lineWidth="0.25"/>
                    <bottomPen lineWidth="0.25"/>
                    <rightPen lineWidth="0.25"/>
                </box>
                <textElement verticalAlignment="Middle"/>
                <textFieldExpression><![CDATA[$F{address}]]></textFieldExpression>
            </textField>
        </band>
    </detail>
</jasperReport>

这个报告没什么特别的,字段对应你data节点中的字段,记得在运行java代码之前把子报告编译成.jasper,因为.jasper在主报告中注明了。

Java 代码

//Get our main report
JasperReport report = JasperCompileManager.compileReport("jsonMain.jrxml");
    
//Open url connection
URLConnection urlConn = new URL("http://www.jdd.it/so/jsonTest.json").openConnection();
//set some cookies
urlConn.setRequestProperty("Cookie", "cookie1=hello; cookie2=world");
    
//Get the stream
try (InputStream is =urlConn.getInputStream()) {
    Map<String, Object> parametersMap = new HashMap<>();
    //Pass to parameter map
    parametersMap.put(JsonQueryExecuterFactory.JSON_INPUT_STREAM, is);
    //Fill report
    JasperPrint jasperPrint = JasperFillManager.fillReport(report, parametersMap);
    //Export to pdf
    JRPdfExporter exporter = new JRPdfExporter();
    exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
    exporter.setExporterOutput(new SimpleOutputStreamExporterOutput("json.pdf"));
    SimplePdfExporterConfiguration configuration = new SimplePdfExporterConfiguration();
    configuration.setMetadataAuthor("Me");
    exporter.setConfiguration(configuration);
    exporter.exportReport();
}

结果

【讨论】:

  • 我想你之前已经从评论中回答了我的问题,我在子报表中写了一个错误的代码,我在子报表中使用 language="groovy",我应该替换 groovy用java。
  • 您也可以在报告中使用 groovy(您只需要类路径中的库)
  • @yuda 在罐子里?,我通常把它们放在外面并传递像c:\\dir\\subreports 这样的值,因此没有文件:罐子里没有子报告。如果您想将它们保存在 jar 中,最好将输入流作为参数传递给每个子报表
  • 在子报表表达式中可能类似getClass().getResource("/reports/mySubreport.jasper").openStream() 也可以工作(类为java.io.InputStream
  • 子报告表达式中没有(如果来自 IDE,jar 需要在类路径中),因此在 jrxml 中(您也可以将其作为 inputstream 或直接来自 java 的 jasper 报告作为参数传递。
【解决方案2】:

这是在更新的 JasperReports 版本 6.3.1 中使用 http 属性和 JSONQL 的方法:

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="JsonHttpDataAdapterReport" columnCount="3" pageWidth="595" pageHeight="842" columnWidth="171" leftMargin="40" rightMargin="40" topMargin="50" bottomMargin="50" uuid="b85a2cf8-dd0c-4a31-804c-e7b217f9b42b">
    <property name="net.sf.jasperreports.data.adapter" value="JsonHttpDataAdapter.xml"/>
    <parameter name="CookieParam" class="java.lang.String" evaluationTime="Early">
        <property name="net.sf.jasperreports.http.data.header" value="Cookie"/>
        <defaultValueExpression><![CDATA["name1=val1;name2=val2"]]></defaultValueExpression>
    </parameter>
    <queryString language="jsonql">
        <![CDATA[data.*]]>
    </queryString>
    <field name="CompanyName" class="java.lang.String">
        <fieldDescription><![CDATA[$.comp_name]]></fieldDescription>
    </field>
    <field name="Title" class="java.lang.String">
        <fieldDescription><![CDATA[$.title]]></fieldDescription>
    </field>
    <field name="Number" class="java.lang.String">
        <fieldDescription><![CDATA[no]]></fieldDescription>
    </field>
    <field name="Name" class="java.lang.String">
        <fieldDescription><![CDATA[name]]></fieldDescription>
    </field>
    <field name="Address" class="java.lang.String">
        <fieldDescription><![CDATA[address]]></fieldDescription>
    </field>
    <background>
        <band splitType="Stretch"/>
    </background>
    <title>
        <band height="79" splitType="Stretch">
            <textField>
                <reportElement x="0" y="0" width="280" height="30" uuid="6333da35-2a4b-4373-9838-2d9e71981516"/>
                <textElement>
                    <font size="20"/>
                </textElement>
                <textFieldExpression><![CDATA[$F{CompanyName}]]></textFieldExpression>
            </textField>
        </band>
    </title>
    <pageHeader>
        <band height="30" splitType="Stretch">
            <textField>
                <reportElement x="0" y="0" width="300" height="30" uuid="4062fecd-290c-4790-8f92-868d4c58f054"/>
                <textElement>
                    <font size="16"/>
                </textElement>
                <textFieldExpression><![CDATA[$F{Title}]]></textFieldExpression>
            </textField>
        </band>
    </pageHeader>
    <columnHeader>
        <band height="31" splitType="Stretch">
            <staticText>
                <reportElement mode="Opaque" x="0" y="0" width="80" height="30" backcolor="#A7E9FA" uuid="b66244aa-5ae0-4e24-9b4f-aafd7f5883cc"/>
                <box topPadding="5" leftPadding="10" bottomPadding="0" rightPadding="0"/>
                <textElement>
                    <font isBold="true"/>
                </textElement>
                <text><![CDATA[Number]]></text>
            </staticText>
            <staticText>
                <reportElement mode="Opaque" x="80" y="0" width="185" height="30" backcolor="#A7E9FA" uuid="965b8d2b-2baf-4842-be30-430ae395a8aa"/>
                <box topPadding="5" leftPadding="10" bottomPadding="0" rightPadding="0"/>
                <textElement>
                    <font isBold="true"/>
                </textElement>
                <text><![CDATA[Name]]></text>
            </staticText>
            <staticText>
                <reportElement mode="Opaque" x="265" y="0" width="255" height="30" backcolor="#A7E9FA" uuid="f56fe462-a90f-4228-a243-3222552f7e45"/>
                <box topPadding="5" leftPadding="10" bottomPadding="0" rightPadding="0"/>
                <textElement>
                    <font isBold="true"/>
                </textElement>
                <text><![CDATA[Address]]></text>
            </staticText>
        </band>
    </columnHeader>
    <detail>
        <band height="30" splitType="Stretch">
            <textField>
                <reportElement x="0" y="0" width="80" height="30" uuid="6b8a6731-19d4-44ee-b41f-c6977729d334"/>
                <box topPadding="5" leftPadding="10"/>
                <textFieldExpression><![CDATA[$F{Number}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="80" y="0" width="185" height="30" uuid="6e51e1eb-ff0e-4e2f-aa05-056060901aff"/>
                <box topPadding="5" leftPadding="10"/>
                <textFieldExpression><![CDATA[$F{Name}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="265" y="0" width="255" height="30" uuid="b79f1a8e-627f-4952-b5eb-632d5db771eb"/>
                <box topPadding="5" leftPadding="10"/>
                <textFieldExpression><![CDATA[$F{Address}]]></textFieldExpression>
            </textField>
        </band>
    </detail>
</jasperReport>

JsonHttpDataAdapter.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<jsonDataAdapter class="net.sf.jasperreports.data.json.JsonDataAdapterImpl">
    <name>JSON Http Data Adapter</name>
    <dataFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xsi:type="httpDataLocation">
        <method>GET</method>
        <url>http://domaindotsomething/data.json</url>
    </dataFile>
    <language>jsonql</language>
    <useConnection>true</useConnection>
    <timeZone xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:java="http://java.sun.com"
              xsi:type="java:java.lang.String">Europe/Bucharest</timeZone>
    <locale xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:java="http://java.sun.com"
            xsi:type="java:java.lang.String">en_US</locale>
    <selectExpression></selectExpression>
</jsonDataAdapter>

还有输出:

编辑:这应该仅被视为 JasperReports v6.3.1 API 解决方案,直到发布了对标头属性/参数的适当支持的更新版本的 JasperSoft Studio。当前最新版本的 JasperSoft Studio v6.3.1 final 阻止预览带有基于 URL 的 JSON 数据适配器的报告。即使来自 6.3.1 标记的 rebuilding JasperSoft Studio 带有阻止其工作的错误的 fix,似乎也不允许此解决方案完全使用基于报告的 http 属性,而只能使用完全配置的 JSON 数据适配器。

【讨论】:

  • 感谢您的回答,我认为这有点复杂,仅针对一个报告我必须为 http 请求创建一个适配器,我需要创建的报告超过 400 个报告。我使用 netbeans 作为 IDE,而 netbeans 对更新 XML 脚本不太友好,如果我更新 XML 脚本,我的报告总是会损坏。
  • 嗯,这只是人们应该知道的一种新的开箱即用的解决方案。您选择最适合您的解决方案。如果它有任何帮助,您还可以拥有一个类似于CookieParamURLParam,它包含net.sf.jasperreports.http.data.url 属性,这样您就不必修改您的适配器文件来提供URL。
  • 好主意,我先试试。另一个问题,为什么我可以使用您的方法访问父级 ($.comp_name)?,为什么我在 ireport 下拉列表中找不到 jsonql
  • 从 5.5.0 版开始,iReport 不再是 JasperReports 的官方设计客户端。见公告here。它被JasperSoft Studio 取代。 JasperReports 的大部分功能仍然可以通过 iReport 访问,但更新/更稳定的功能需要 Studio 应用程序。我发布的那些功能(http 属性和 JSONQL)是最新的 JasperReports 公开版本的一部分,并且仍在设计客户端的开发中。
  • JasperReports 的大多数新的和现有的主要功能总是可以通过JasperReports Sample Reference 页面发现。
猜你喜欢
  • 2018-07-27
  • 2022-11-07
  • 2014-11-05
  • 2019-08-27
  • 1970-01-01
  • 1970-01-01
  • 2017-06-03
  • 1970-01-01
  • 2014-11-05
相关资源
最近更新 更多