如何将我的 Hashmap <key, list> 设置为 jasper 报告的数据源

How to setup my Hashmap <key, list> as a datasource for jasper reports

我需要将 HashMap 对象显示为 jasper 数据源

Map<String, List<obj>> salesMap= new HashMap<>();    
salesMap.put("10/02/2021", List<Obj>);
salesMap.put("11/02/2021", List<Obj>);
salesMap.put("12/02/2021", List<Obj>);

和我的数据源

private JRMapCollectionDataSource fuelSalesDataSource;

public Map<String, Object> getDataSources() {
    Map<String, Object> dataSources = new HashMap<>();
    dataSources.put("fuelSalesDataSource", fuelSalesDataSource);
    return dataSources;
}

还有我的碧玉印花

    JRMapArrayDataSource dataSource = new JRMapArrayDataSource(
            new Object[] { fuelSalesReportInputMO.getDataSources() });

    JasperReport jasperReport = JasperCompileManager.compileReport(fuel_sales_report);

    JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, fuelSalesReportInputMO.getParameters(),
            dataSource);

    reportData = JasperExportManager.exportReportToPdf(jasperPrint);

我必须在 jasper 中显示我的 HashMap,如何在一行中获取哈希映射键及其对象列表?

       key column          value column          value column     
       10/02/2021         list[0].getType       list[1].getType
       11/02/2021         list[0].getType       list[1].getType.

我在 jrmxl 中有字段

<field name="fuelSalesDataSource" class="net.sf.jasperreports.engine.data.JRMapCollectionDataSource"/>

 

如何在jrxml中通过键读取map,其值作为列表?

重读此文后,我认为您对集合使用了错误的数据类型。您正在使用:

JRMapCollectionDataSource 期望 Collection<Map> 这不是你所拥有的。您有一个 Map 想要迭代。

你正在包装的

JRMapArrayDataSource 需要一个 Array<Map>,您只是将其与您的单个地图数据集合一起传入数组 [1]。

假设您想要所有 dates = row 您需要传入多张地图。可能看起来像这样的东西:

data: [
   { date: "10/02/2021", data: List<Obj>) },
   { date: "11/02/2021", data: List<Obj>) },
   { date: "12/02/2021", data: List<Obj>) },
]

现在您可以直接传入 JRMapCollectionDataSource 而无需对其进行包装。现在您可以将字段设置为:

  • THIS = java.util.Map(如果你想直接访问)
  • 日期 = java.util.Date
  • 数据=java.util.List

这将允许您设置报告:

[文本字段:$F{日期}] [列表:新的 JRBeanCollectionDataSource($F{data}),横向]

这应该让您接近您正在寻找的输出。

如果这离题太远,抱歉。

Jasper 报告是一种报告工具,可以使用 JRMapCollectionDataSource 或任何其他类型,然后引用列表,对象在特定文本字段中列表中的位置,但是由于在我看来,您正在 java 中创建数据,您应该将所有这些逻辑保留在 java 中。当您可以在 java 应用程序中以干净的方式解决问题时,尝试在 jasper 报告中解决问题是没有意义的。

这就是我会做的:

创建一个 class 表示报告中的输出

@Data // lombok that generates getter/setter (if you don't have it do them in code)
public class ReportData {   
    private String date;
    private String value1;
    private String value2;
}

然后在java设置数据

final List<ReportData> data = new ArrayList<>();

//Maybe add some sorting (HashMap is unsorted)?
salesMap.entrySet().stream().forEach(e -> {
    
    ReportData rp = new ReportData();
    rp.setDate(e.getKey());
    //Here you should check size of list etc 
    rp.setValue1(e.getValue().get(0));
    rp.setValue2(e.getValue().get(1));
    data.add(rp)
});

//Then now pass it to report
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, fuelSalesReportInputMO.getParameters(),
            new JRBeanCollectionDataSource(data));

就像现在在 jasper 报告中一样,您只需 ReportData 中的字段名称,例如

<field name="date" class="java.lang.String"/>

我已经解决了这个问题,正如@Petter 所指出的,我将我的数据源从 JRMapCollection 更改为 JRBeanCollectionDataSource...

下面的代码

public JRBeanCollectionDataSource  getFuelSalesReportDataSource() {
    Map<String, List<DailyFuelSalesMO>> sortedMap = new TreeMap<>(dailyFuelSalesMap);
    Set<Entry<String,List<DailyFuelSalesMO>>> set = sortedMap.entrySet();
    fuelSalesReportDataSource = new JRBeanCollectionDataSource(set);
    return fuelSalesReportDataSource;
}

和 jrxml,我有如下字段..

    <field name="key" class="java.lang.String"/>
    <field name="value[0].fuelObj.type" class="java.lang.Object"/>
    <field name="value[0].fuelObj.priceObj.price" class="java.lang.Double"/>         
    <field name="value[1].fuelObj.type" class="java.lang.Object"/>
    <field name="value[1].fuelObj.priceObj.price" class="java.lang.Double"/>

所以我可以用键和它的列表值填充单行,在这里我每个键有两个列表对象,所以我可以通过值 [i] 为每个键对象获取这些对象在哈希图中...