Apache POI:按日期排序行

时间:2016-10-14 10:58:13

标签: java excel sorting apache-poi

我正在使用Apache POI从XML创建Excel文档。我有一个日期值的单元格,我将其设为日期:

HSSFCellStyle styleDate = workbook.createCellStyle();
HSSFDataFormat dataFormat = workbook.createDataFormat();
styleDate.setDataFormat(dataFormat.getFormat("dd/mm/yyyy Hh:mm"));
styleDate.setAlignment(HorizontalAlignment.CENTER);

excel中的数据显示为日期。我需要在Excel文档中按日期按升序对其进行排序。

我知道POI没有内置的排序功能,我不能使用Aspose Cells,因为我没有获得业务方面的额外许可费用。

Excel文件结构: 片:

1. Item 1: 01/01/2016 (sorted correctly using HashMap sorting)
1.1. Sub item 1: 01/01/2016 02:00 (not sorted, needs to be sorted)
1.2. Sub item 2: 01/01/2016 05:00 (not sorted, needs to be sorted)
1.3. Sub item 3: 01/01/2016 01:00 (not sorted, needs to be sorted)

2. Item 2: 02/01/2016 (sorted correctly using HashMap sorting)
2.1. Sub item 1: 02/01/2016 02:00 (not sorted, needs to be sorted)
2.2. Sub item 2: 02/01/2016 05:00 (not sorted, needs to be sorted)
2.3. Sub item 3: 02/01/2016 01:00 (not sorted, needs to be sorted)

HashMap排序

for (int i = 0; i < nodeList.getLength(); i++) {
    itemHashMap.put(getNodeValue(nodeList, i, "item"),
                                getNodeValue(nodeList, i, "itemDate"));
}

3 个答案:

答案 0 :(得分:4)

private void sortSheet(Sheet sheet, int column, int rowStart) {
 boolean sorting = true;
 int lastRow = sheet.getLastRowNum();
 while (sorting) {
    sorting = false;
    for (Row row : sheet) {
        if (row.getRowNum() < rowStart) continue;
        if (lastRow == row.getRowNum()) break;
        Row nextRow = sheet.getRow(row.getRowNum() + 1);
        if (nextRow == null) continue;
        Date firstValue = row.getCell(column).getDateCellValue() ;
        Date secondValue = nextRow.getCell(column).getDateCellValue() ;
        if (secondValue.before(firstValue)) {                    
            sheet.shiftRows(nextRow.getRowNum(), nextRow.getRowNum(), -1);
            sheet.shiftRows(row.getRowNum(), row.getRowNum(), 1);
            sorting = true;
        }
    }
 }
}

答案 1 :(得分:1)

不要将Date对象转换为String。而是直接在模型中使用它们。建议格式化不是模型的责任,而是使用TableCellRenderer。

允许getValueAt返回Date对象。

修改表模型并覆盖getColumnClass方法并返回hiven列的批准类(如Date.class)。

默认情况下,表格会为您设置Date对象的格式。

答案 2 :(得分:0)

目前,Apache POI不允许以简单的方式对生成的excel文件中的数据进行排序。

您当然可以使用Aspose,但这需要许可证。我将由Apache POI处理并用于end excel文档的传入数据采用XML格式:

<transaction>
    <transactionDate>2015-10-23T00:00:00+03:00</transactionDate>
    <transactionAmount>23</transactionAmount>
    <transactionBatch>000</transactionBatch>
    <transactionBatchDate>2015-10-27T10:12:00+02:00</transactionBatchDate>
    <transactionServiceFee>1</transactionServiceFee>
    <transactionNetAmount>22</transactionNetAmount>
</transaction>
<transaction>
    <transactionDate>2016-02-25T11:13:59+02:00</transactionDate>
    <transactionAmount>-1000</transactionAmount>
    <transactionBatch>000</transactionBatch>
    <transactionBatchDate>2016-02-25T11:14:40+02:00</transactionBatchDate>
    <transactionServiceFee>-30</transactionServiceFee>
    <transactionNetAmount>-970</transactionNetAmount>
</transaction>
    <transaction>
    <transactionDate>2015-10-23T00:00:00+03:00</transactionDate>
    <transactionAmount>23</transactionAmount>
    <transactionBatch>001</transactionBatch>
    <transactionBatchDate>2015-10-27T10:12:00+02:00</transactionBatchDate>
    <transactionServiceFee>1</transactionServiceFee>
    <transactionNetAmount>22</transactionNetAmount>
</transaction>
<transaction>
    <transactionDate>2016-02-25T11:13:59+02:00</transactionDate>
    <transactionAmount>-1000</transactionAmount>
    <transactionBatch>001</transactionBatch>
    <transactionBatchDate>2016-02-25T11:14:40+02:00</transactionBatchDate>
    <transactionServiceFee>-30</transactionServiceFee>
    <transactionNetAmount>-970</transactionNetAmount>
</transaction>
....

我必须在结果Excel中以下列方式显示数据:

1. transactionBatch 000: transactionBatchDate (sorted by date in asc.)
1.1. transaction: transactionDate (sorted by date grouped by above batch)
1.2. transaction: transactionDate (sorted by date grouped by above batch)
1.3. transaction: transactionDate (sorted by date grouped by above batch)

2. transactionBatch 001: transactionBatchDate (sorted by date in asc.)
2.1. transaction: transactionDate (sorted by date grouped by above batch)
2.2. transaction: transactionDate (sorted by date grouped by above batch)
2.3. transaction: transactionDate (sorted by date grouped by above batch)

为了解决我的问题,我首先必须按日期对XML中的数据进行排序。这是通过让我的模型实现Comparable接口来实现的。

我可以按照这样的日期批次进行排序:

Map<String, String> transactionBatchHashMap = new HashMap<>();
for (int i = 0; i < nodeList.getLength(); i++) {
            transactionBatchHashMap.put(getNodeValue(nodeList, i, "transactionBatch"),
                                        getNodeValue(nodeList, i, "transactionBatchDate"));
        }

        transactionBatchHashMap = sortMapByValues(transactionBatchHashMap);

然后通过使用一个简单的foreach循环,我可以对每个批次下的事务进行分组:

for (Map.Entry<String, String> entry : transactionBatchHashMap.entrySet()) {

            HSSFRow batchRow = spreadSheet.createRow(rowNumber);
            ...

            for (int i = 0; i < nodeList.getLength(); i++) {
                String transactionBatchValue = getNodeValue(nodeList, i, "transactionBatch");
                String hashMapBatchKeyValue = entry.getKey();

                if (transactionBatchValue.equals(hashMapBatchKeyValue)) {   
                ...