2

我有以下包含循环的代码块:

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

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"));
            }
            sheet.autoSizeColumn(i);
        }
    }

每个对象包含 4 个值myDataValuesList哪里。String[]String[]

我在 Rational Application Developer 版本 8 和 Apache POI 3.8 中运行它。

大约有 5500 个元素,myDataValues我认为这是一个很小的值。

但是,此代码块需要一个多小时才能运行。

我认为这有问题。5500 个元素,每个元素包含 4 个元素,运行速度应该非常快,应该是几分钟的问题。可能的原因是什么?有没有办法让这个块运行得更快?

机器的可用内存或任何其他此类问题没有任何问题。一切都按预期工作,我已经验证过了。问题仅在此块中。

4

3 回答 3

8

您的处理速度非常慢,因为您正在调用autoSizeColumn每一行。来自该方法的JavadocsautoSizeColumn

此过程在大型工作表上可能相对较慢,因此通常应在处理结束时每列调用一次。

将调用放在创建行的循环之外,仅在列上的autoSizeColumn自己的循环中。for这将最大限度地减少对该方法的调用并提高您的性能。

于 2013-09-24T16:03:37.767 回答
2

仅供参考...

就我而言,我有 100 万多,而且 AutoSizeColumn 仍然很慢(即使到最后)。

所以,我考虑提高性能,只存储每个值的列索引和内容长度(在字典中),当它比上次存储的大时。

在所有过程结束时,只需“foreach”列表并使用 sheet.SetColumnWidth 设置列的宽度。

  • 自动调整大小:永无止境;
  • 宽度:3 秒。

伪代码

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;
                }

最后

foreach (KeyValuePair<int, int> column in dictionary)
        {
            sheet.SetColumnWidth(column.Key, column.Value*300);
        }
于 2020-03-19T19:05:07.940 回答
0

尝试这个...

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);
    }
于 2013-09-24T15:46:57.960 回答