A POI related code block running dead slow

后端 未结 3 691
再見小時候
再見小時候 2020-12-20 08:23

I have below piece of code block containing loops:

Row row = null;
Cell cell = null;
String dataVal = null;
String[] temp = null;

for (int j = 0; j < thi         


        
相关标签:
3条回答
  • 2020-12-20 08:39

    try this...

    for (int j = 0; j < this.myDataValues.size(); j++) {
      row = sheet.createRow(rownum++);
      temp = this.finalRowValues.get(j);
    
       for (int i = 0; i < 4; i++) {
           cell = row.createCell(i);
    
           dataVal = temp[i];
    
                if (NumberUtils.isNumber(dataVal)) {
                    double d = Double.valueOf(dataVal);
                    cell.setCellValue(d);
                    cell.setCellType(Cell.CELL_TYPE_NUMERIC);
                    cell.setCellStyle(styles.get("currency"));
                } else if (isValidDate(dataVal)) {
                    cell.setCellValue(dataVal);
                    cell.setCellType(Cell.CELL_TYPE_NUMERIC);
                    cell.setCellStyle(styles.get("date"));
                } else {
                    cell.setCellValue(temp[i]);
                    cell.setCellType(Cell.CELL_TYPE_STRING);
                    cell.setCellStyle(styles.get("data"));
                }
            }
        }
        for (int i = 0; i < 4; i++) {
          sheet.autoSizeColumn(i);
        }
    
    0 讨论(0)
  • 2020-12-20 08:52

    Your processing is very slow because you're calling autoSizeColumn for every row. From the Javadocs for the autoSizeColumn method:

    This process can be relatively slow on large sheets, so this should normally only be called once per column, at the end of your processing.

    Place the calls to autoSizeColumn outside of the loop that creates the rows, in its own for loop only on the columns. This will minimize calls to this method and improve your performance.

    0 讨论(0)
  • 2020-12-20 08:53

    Just for reference...

    In my case, I had 1 millions plus, and the AutoSizeColumn still slow (even in the end).

    So, I considerely boost the performance, just storing the column index and content length of every values (in a Dictionary), when it is large than last stored.

    In the end of all process, just "foreach" the list and set the width of the column with sheet.SetColumnWidth.

    • With autosize: never end;
    • With witdh: 3 seconds.

    Pseudo-code

    if(!dictionary.Any(a => a.Key == columnIndex))
                    {
                        dictionary.Add(columnIndex, columnContent.Length);
                    }
                    else if(dictionary.Any(a => a.Key == columnIndex && a.Value < columnContent.Length))
                    {
                        dictionary[columnIndex] = columnContent.Length;
                    }
    

    And in the end

    foreach (KeyValuePair<int, int> column in dictionary)
            {
                sheet.SetColumnWidth(column.Key, column.Value*300);
            }
    
    0 讨论(0)
提交回复
热议问题