spring 报告在后端很好,但从Sping Boot 使用 AJAX 下载时收到的报告为空

zbwhf8kr  于 2022-11-28  发布在  Spring
关注(0)|答案(2)|浏览(84)

"我的筹码"
Spring Boot 1.5.6
Jasper报表
AJAX 查询3.1.1

我的目标

我试图打印第一次使用jasper报告的报告,我有一个打印服务,我有我的报告存储,我的想法是通过ajax发送http请求包含数据,并获得一个pdf报告
"我的努力"
我在spring-boot后端中有一个rest控制器,它是这样实现的

@RestController
@RequestMapping(PrintController.API)
public class PrintController {
    public static final String API="print";

    @PostMapping("client")
    public void export(@RequestBody List<ClientJsonDto> datas,HttpServletResponse response){

        System.out.println(datas);
         JRBeanCollectionDataSource itemsJRBean = new JRBeanCollectionDataSource(datas);

    /* Map to hold Jasper report Parameters */
    Map<String, Object> parameters = new HashMap<String, Object>();
    parameters.put("ItemDataSource", itemsJRBean);

    byte[] bytes = generatePDFReport("refclient", parameters);
    return ResponseEntity
              .ok()
              // Specify content type as PDF
              .header("Content-Type", "application/pdf; charset=UTF-8")
              // Tell browser to display PDF if it can
              .header("Content-Disposition", "attachment;inline; filename=\"client.pdf\"")
              .body(bytes);
       
    }

public byte[] generatePDFReport(String inputFileName, Map<String, Object> params) {
    return generatePDFReport(inputFileName, params, new JREmptyDataSource());
}

    
public File loadJasperFile(String file) {
    
    try {
        return ResourceUtils.getFile("classpath:static/reports/"+file+".jasper");
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    };
    return null;
}

public byte[] generatePDFReport(String inputFileName, Map<String, Object> params,
        JRDataSource dataSource) {
        byte[] bytes = null;
        JasperReport jasperReport = null;
        try (ByteArrayOutputStream byteArray = new ByteArrayOutputStream()) {
          // Check if a compiled report exists

            jasperReport = (JasperReport) JRLoader.loadObject(loadJasperFile(inputFileName));
          
          // Compile report from source and save
       
          JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params, dataSource);
          // return the PDF in bytes
          bytes = JasperExportManager.exportReportToPdf(jasperPrint);
        }
        catch (JRException | IOException e) {
          e.printStackTrace();
        }
        return bytes;
      }

}

我报告如下

<?xml version="1.0" encoding="UTF-8"?>
    <!-- Created with Jaspersoft Studio version 7.2.0.final using JasperReports Library version 6.6.0  -->
    <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="refClient" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" isIgnorePagination="true" uuid="576dcd38-2982-412b-93d5-2a078da1b183">
        <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
        <style name="Table_TH" mode="Opaque" backcolor="#F0F8FF">
            <box>
                <pen lineWidth="0.5" lineColor="#000000"/>
                <topPen lineWidth="0.5" lineColor="#000000"/>
                <leftPen lineWidth="0.5" lineColor="#000000"/>
                <bottomPen lineWidth="0.5" lineColor="#000000"/>
                <rightPen lineWidth="0.5" lineColor="#000000"/>
            </box>
        </style>
        <style name="Table_CH" mode="Opaque" backcolor="#BFE1FF">
            <box>
                <pen lineWidth="0.5" lineColor="#000000"/>
                <topPen lineWidth="0.5" lineColor="#000000"/>
                <leftPen lineWidth="0.5" lineColor="#000000"/>
                <bottomPen lineWidth="0.5" lineColor="#000000"/>
                <rightPen lineWidth="0.5" lineColor="#000000"/>
            </box>
        </style>
        <style name="Table_TD" mode="Opaque" backcolor="#FFFFFF">
            <box>
                <pen lineWidth="0.5" lineColor="#000000"/>
                <topPen lineWidth="0.5" lineColor="#000000"/>
                <leftPen lineWidth="0.5" lineColor="#000000"/>
                <bottomPen lineWidth="0.5" lineColor="#000000"/>
                <rightPen lineWidth="0.5" lineColor="#000000"/>
            </box>
        </style>
        <style name="Table 1_TH" mode="Opaque" backcolor="#F0F8FF">
            <box>
                <pen lineWidth="0.5" lineColor="#000000"/>
                <topPen lineWidth="0.5" lineColor="#000000"/>
                <leftPen lineWidth="0.5" lineColor="#000000"/>
                <bottomPen lineWidth="0.5" lineColor="#000000"/>
                <rightPen lineWidth="0.5" lineColor="#000000"/>
            </box>
        </style>
        <style name="Table 1_CH" mode="Opaque" backcolor="#BFE1FF">
            <box>
                <pen lineWidth="0.5" lineColor="#000000"/>
                <topPen lineWidth="0.5" lineColor="#000000"/>
                <leftPen lineWidth="0.5" lineColor="#000000"/>
                <bottomPen lineWidth="0.5" lineColor="#000000"/>
                <rightPen lineWidth="0.5" lineColor="#000000"/>
            </box>
        </style>
        <style name="Table 1_TD" mode="Opaque" backcolor="#FFFFFF">
            <box>
                <pen lineWidth="0.5" lineColor="#000000"/>
                <topPen lineWidth="0.5" lineColor="#000000"/>
                <leftPen lineWidth="0.5" lineColor="#000000"/>
                <bottomPen lineWidth="0.5" lineColor="#000000"/>
                <rightPen lineWidth="0.5" lineColor="#000000"/>
            </box>
        </style>
        <subDataset name="ItemDataset" uuid="2914f7c6-c2d7-448b-b0c1-090970e18ed6">
            <queryString>
                <![CDATA[]]>
            </queryString>
            <field name="clientName" class="java.lang.String"/>
            <field name="identifiant" class="java.lang.String"/>
            <field name="codeExterne" class="java.lang.String"/>
        </subDataset>
        <parameter name="ItemDataSource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
        <queryString>
            <![CDATA[select 1 from dual]]>
        </queryString>
        <background>
            <band splitType="Stretch"/>
        </background>
        <title>
            <band height="50">
                <staticText>
                    <reportElement x="11" y="11" width="100" height="30" uuid="9d66bc1e-2b6d-49b7-8a64-74fbd2e5d5eb"/>
                    <text><![CDATA[Liste des clients]]></text>
                </staticText>
            </band>
        </title>
        <detail>
            <band height="256" splitType="Stretch">
                <componentElement>
                    <reportElement x="0" y="0" width="555" height="200" uuid="7786bb05-503a-4b6a-991a-a7bcf3abad07">
                        <property name="com.jaspersoft.studio.layout" value="com.jaspersoft.studio.editor.layout.VerticalRowLayout"/>
                        <property name="com.jaspersoft.studio.table.style.table_header" value="Table 1_TH"/>
                        <property name="com.jaspersoft.studio.table.style.column_header" value="Table 1_CH"/>
                        <property name="com.jaspersoft.studio.table.style.detail" value="Table 1_TD"/>
                    </reportElement>
                    <jr:table xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd">
                        <datasetRun subDataset="ItemDataset" uuid="d3e1e03a-2c83-4436-9e50-79518bc3d337">
                            <dataSourceExpression><![CDATA[$P{ItemDataSource}]]></dataSourceExpression>
                        </datasetRun>
                        <jr:column width="130" uuid="dca8961f-ce2d-47ac-879c-b15847d170a9">
                            <property name="com.jaspersoft.studio.components.table.model.column.name" value="Colonne1"/>
                            <jr:tableHeader style="Table 1_TH" height="30" rowSpan="1">
                                <staticText>
                                    <reportElement x="0" y="0" width="130" height="30" uuid="f60d1675-6fb6-4569-93ca-de32b3a8e861"/>
                                    <box>
                                        <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                    </box>
                                    <text><![CDATA[Nom]]></text>
                                </staticText>
                            </jr:tableHeader>
                            <jr:detailCell style="Table 1_TD" height="30">
                                <textField>
                                    <reportElement x="0" y="0" width="130" height="30" uuid="f1de366a-b36f-4200-9b1e-7a0009be5373"/>
                                    <box>
                                        <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                    </box>
                                    <textFieldExpression><![CDATA[$F{clientName}]]></textFieldExpression>
                                </textField>
                            </jr:detailCell>
                        </jr:column>
                        <jr:column width="140" uuid="980fffb5-1088-47a6-b00f-b5d08b7093c9">
                            <property name="com.jaspersoft.studio.components.table.model.column.name" value="Colonne2"/>
                            <jr:tableHeader style="Table 1_TH" height="30" rowSpan="1">
                                <staticText>
                                    <reportElement x="0" y="0" width="140" height="30" uuid="16679b95-2e6e-4ca1-b8b6-dd7b74267c56"/>
                                    <box>
                                        <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                    </box>
                                    <text><![CDATA[Identifiant]]></text>
                                </staticText>
                            </jr:tableHeader>
                            <jr:detailCell style="Table 1_TD" height="30">
                                <textField>
                                    <reportElement x="0" y="0" width="140" height="30" uuid="341e7faf-9680-4941-a9a4-ac78b8f4aae0"/>
                                    <box>
                                        <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                    </box>
                                    <textFieldExpression><![CDATA[$F{identifiant}]]></textFieldExpression>
                                </textField>
                            </jr:detailCell>
                        </jr:column>
                        <jr:column width="100" uuid="761d1134-6b53-4b5d-9355-b44586d8d8aa">
                            <property name="com.jaspersoft.studio.components.table.model.column.name" value="Colonne3"/>
                            <jr:tableHeader style="Table 1_TH" height="30" rowSpan="1">
                                <staticText>
                                    <reportElement x="0" y="0" width="100" height="30" uuid="b07f5db5-1df8-48e9-a612-27ad6110fdcd"/>
                                    <box>
                                        <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                    </box>
                                    <text><![CDATA[Code]]></text>
                                </staticText>
                            </jr:tableHeader>
                            <jr:detailCell style="Table 1_TD" height="30">
                                <textField>
                                    <reportElement x="0" y="0" width="100" height="30" uuid="1e0438b1-82e5-429a-b63a-5349014cf84a"/>
                                    <box>
                                        <topPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <leftPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <bottomPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                        <rightPen lineWidth="1.0" lineStyle="Solid" lineColor="#000000"/>
                                    </box>
                                    <textFieldExpression><![CDATA[$F{codeExterne}]]></textFieldExpression>
                                </textField>
                            </jr:detailCell>
                        </jr:column>
                    </jr:table>
                </componentElement>
            </band>
        </detail>
    </jasperReport>

如您所见,我在发送jrcollection时使用了一个参数,这是我在YouTube上找到的教程中使用的参数。
对于响应处理,我使用了以下js ajax调用

$(document).on('click', '#menu0-func1-menu0-func1', function(){
        console.log(printData);
        var jsonData =JSON.parse(JSON.stringify(printData));
            var settings = {
                "async" : true,
                "crossDomain" : true,
                "url" : "http://"+document.location.host+"/facturation/print/client",
                "method" : "POST",
                "headers" : {
                    "cache-control" : "no-cache",
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                },
                "processData" : false,
                "contentType" : "application/json",
                "dataType" : "text",
                "data" : JSON.stringify(printData)
            }

            $.ajax(settings).done(function(response, status, xhr) {
                console.log(response);
                  
                // check for a filename
                var filename = "";
                var disposition = xhr.getResponseHeader('Content-Disposition');
                if (disposition && disposition.indexOf('attachment') !== -1) {
                    var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
                    var matches = filenameRegex.exec(disposition);
                    if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
                }

                var type = xhr.getResponseHeader('Content-Type');
                var blob = new Blob([response], { type: type });

                if (typeof window.navigator.msSaveBlob !== 'undefined') {
                    // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
                    window.navigator.msSaveBlob(blob, filename);
                } else {
                    var URL = window.URL || window.webkitURL;
                    var downloadUrl = URL.createObjectURL(blob);

                    if (filename) {
                        // use HTML5 a[download] attribute to specify filename
                        var a = document.createElement("a");
                        // safari doesn't support this yet
                        if (typeof a.download === 'undefined') {
                            window.location = downloadUrl;
                        } else {
                            a.href = downloadUrl;
                            a.download = filename;
                            document.body.appendChild(a);
                            a.click();
                        }
                    } else {
                        window.location = downloadUrl;
                    }

                    setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
                }
            
            });
    });

没有例外,通常我至少应该得到报告的标题,但我得到的是一个空的pdf页面
这是我在Chrome中控制台日志

%PDF-1.5
    %����
    3 0 obj
    <</Filter/FlateDecode/Length 882>>stream
    x���[O1���W��>�z|�M^i�J�B�T��e�Q��`����zJc�����}|2_���hU�R,d)Vuq�*�J�u!�W�{a�X�w' @�US�Y�t��D��ޤ�)�e��Ӧ8��m�ע^���n��n�#���9��O�\�ג�K��Rֺw�����
    �r��59��>/� 0^���r�`ޙ�ֈ�h�!�`�/���5�KƆ��Yb�\
    #��1hP�
    �ďK.fYyk?���%�6T�!�}�˾(j�on7����M���?F6���V��F�M^&�IjywI�h��������WV1d���L2N�w��̦%�E�c�B��I��єB�R��b!�2�f���d=*�I�����"�KB�"
    ��᳍&�������ֲX�df2��C"�zf�#)Ό�wLJ��F����аH��E#
    ��%/!b=��,�"y�XKyA˿��e
    endstream
    endobj
    1 0 obj
    <</Tabs/S/Group<</S/Transparency/Type/Group/CS/DeviceRGB>>/Contents 3 0 R/Type/Page/Resources<</ColorSpace<</CS/DeviceRGB>>/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]/Font<</F1 2 0 R>>>>/Parent 4 0 R/MediaBox[0 0 595 842]>>
    endobj
    5 0 obj
    [1 0 R/XYZ 0 852 0]
    endobj
    2 0 obj
    <</Subtype/Type1/Type/Font/BaseFont/Helvetica/Encoding/WinAnsiEncoding>>
    endobj
    4 0 obj
    <</Kids[1 0 R]/Type/Pages/Count 1/ITXT(2.1.7)>>
    endobj
    6 0 obj
    <</Names[(JR_PAGE_ANCHOR_0_1) 5 0 R]>>
    endobj
    7 0 obj
    <</Dests 6 0 R>>
    endobj
    8 0 obj
    <</Names 7 0 R/Type/Catalog/Pages 4 0 R/ViewerPreferences<</PrintScaling/AppDefault>>>>
    endobj
    9 0 obj
    <</ModDate(D:20181123161409Z)/Creator(JasperReports Library version 6.4.0)/CreationDate(D:20181123161409Z)/Producer(iText 2.1.7 by 1T3XT)>>
    endobj
    xref
    0 10
    0000000000 65535 f 
    0000000964 00000 n 
    0000001240 00000 n 
    0000000015 00000 n 
    0000001328 00000 n 
    0000001205 00000 n 
    0000001391 00000 n 
    0000001445 00000 n 
    0000001477 00000 n 
    0000001580 00000 n 
    trailer
    <</Info 9 0 R/ID [<b7d27a6f96e6278f5c1d222f79d7c999><b97ae89e1e568703aeb75af2080d04d8>]/Root 8 0 R/Size 10>>
    startxref
    1735
    %%EOF

怎么办,我尝试了很多教程这3最后几天,但没有成功

编辑

我使用JasperExportManager.exportReportToPdfFile(jasperPrint, "rapport.pdf");生成了pdf,pdf文件格式良好,我将此良好pdf的txt表示形式与收到的日志进行了比较,它们是相同的,我的空pdf为3 kb,格式良好的PDF也为3 kb。

h4cxqtbf

h4cxqtbf1#

你不能下载文件通过 AJAX 调用我建议你的是:

安杰洛

brccelvz

brccelvz2#

我试过你的javascript代码,确实有一个问题。
但是问题来自于jQuery的 AJAX 实现,它没有正确处理响应数据类型。
这篇文章here提供了两种选择:请直接使用XMLHttpRequest对象或使用专门为此问题设计的自定义jQuery plugin
另一个选择是将控制器逻辑分为两部分:

  • 在第一次请求时,您需要填写报表参数
  • 在第二个窗口中,您将生成PDF输出;您甚至可以在一个新的选项卡中打开它并跳过整个 AJAX 部分。

相关问题