我使用OpenXML v 2.8.1.0为网站创建Excel报告。电子表格有22列。渲染15,000行需要30秒,但这对于网页来说太长了。我可以更有效地做到这一点吗?
代码段位于下面(省略了与该问题无关的部分)。怀疑我在遍历每个单元格以设置其单元格引用,然后还设置每一行的rowIndex方面的效率低下。
我在打开要填充的电子表格的地方遗漏了代码-它包含标题和示例详细信息行,其中包含我想要的所有格式,但所有值均为空白。
在代码中,我克隆该行,为每个单元格设置值和单元格引用,为该行设置rowIndex,插入该行,然后从数据库中获取下一行数据并重复。
还是每秒500行大约和OpenXML一样快?
谢谢。
public class MyReport
{
public byte[] Get(List<dbRow> dbRows)
{
// dbRows is the result of "Select col0, col1, ... col21 from dbTable"
// first 6 rows are the report headers
// row 7 is the blank detail row.
Row templateDetailRow = sheetData.Elements<Row>().Where(r => r.RowIndex == 7).First();
// start inserting data rows at row number 8
uint currentRowPointer = sheetData.Elements<Row>().LastOrDefault().RowIndex + 1; // start adding rows after the current last row
Row currentBottomRow = sheetData.Elements<Row>().LastOrDefault(); // initialize to last row before we start adding rows
foreach (dbRow r in dbRows)
{
Row newRow = (Row)templateDetailRow.Clone();
List<Cell> cells = newRow.Elements<Cell>().OrderBy(c => c.CellReference.Value).ToList();
SetCellsInRow(cells, r, currentRowPointer);
newRow.RowIndex = currentRowPointer;
InsertRow(sheetData, newRow);
currentRowPointer++;
}
}
private void SetCellsInRow(List<Cell> cells, dbRow source, uint rowIndex)
{
SetCell(cells[0], source.string0, rowIndex);
SetCell(cells[1], source.int1, rowIndex);
SetCell(cells[2], source.string2, rowIndex);
SetCell(cells[3], source.string3, rowIndex);
SetCell(cells[4], source.string4, rowIndex);
SetCell(cells[5], String.Format("{0:MM/dd/yyyy}", source.date5), rowIndex);
SetCell(cells[6], source.string6, rowIndex);
SetCell(cells[7], source.int7, rowIndex);
SetCell(cells[8], source.string8, rowIndex);
SetCell(cells[9], source.string9, rowIndex);
SetCell(cells[10], source.date10.ToString("MM/dd/yyyy"), rowIndex);
SetCell(cells[11], String.Format("{0:MM/dd/yyyy}", source.date11), rowIndex);
SetCell(cells[12], String.Format("{0:MM/dd/yyyy}", source.date12), rowIndex);
SetCell(cells[13], source.string13, rowIndex);
SetCell(cells[14], String.Format("{0:MM/dd/yyyy}", source.date14), rowIndex);
SetCell(cells[15], source.int15 ?? 0, rowIndex);
SetCell(cells[16], String.Format("{0:MM/dd/yyyy}", source.date16), rowIndex);
SetCell(cells[17], source.string17, rowIndex);
SetCell(cells[18], source.string18, rowIndex);
SetCell(cells[19], source.int19, rowIndex);
SetCell(cells[20], source.string20, rowIndex);
SetCell(cells[21], source.string21, rowIndex);
}
private void SetCell(Cell theCell, string val, uint rowIndex)
{ // a NON-SHARED string is going in to the cell
theCell.CellValue = new CellValue(val);
theCell.DataType = new EnumValue<CellValues>(CellValues.String);
theCell.CellReference = Regex.Replace(theCell.CellReference, @"\d+", rowIndex.ToString());
}
private void SetCell(Cell theCell, int val, uint rowIndex)
{ // an int is going in to the cell
theCell.CellValue = new CellValue(val.ToString());
theCell.DataType = new EnumValue<CellValues>(CellValues.Number);
theCell.CellReference = Regex.Replace(theCell.CellReference, @"\d+", rowIndex.ToString());
}
private static void InsertRow(SheetData sheetData, Row row)
{
sheetData.InsertAfter(row, currentBottomRow);
currentBottomRow = row;
}
}
答案 0 :(得分:0)
收到对social.msdn上发布的相同问题的很好回答:
忘记尝试设置rowIndex和CellReference会更快。而是将它们保留为空,并使用AppendChild。这是我改进的代码:
public class MyReport
{
public byte[] Get(List<dbRow> dbRows)
{
// dbRows is the result of "Select col0, col1, ... col21 from dbTable"
foreach (dbRow r in dbRows)
{
Row newRow = new Row();
SetCell(r.string0, newRow);
SetCell(r.int1, newRow);
SetCell(r.string2, newRow);
SetCell(r.string3, newRow);
SetCell(r.string4, newRow);
SetCell(String.Format("{0:MM/dd/yyyy}", r.date5), newRow);
SetCell(r.string6, rowIndex);
SetCell(r.int7, rowIndex);
SetCell(r.string8, rowIndex);
SetCell(r.string9, rowIndex);
SetCell(r.date10.ToString("MM/dd/yyyy"), rowIndex);
SetCell(String.Format("{0:MM/dd/yyyy}", r.date11), rowIndex);
SetCell(String.Format("{0:MM/dd/yyyy}", r.date12), rowIndex);
SetCell(r.string13, rowIndex);
SetCell(String.Format("{0:MM/dd/yyyy}", r.date14), rowIndex);
SetCell(r.int15 ?? 0, rowIndex);
SetCell(String.Format("{0:MM/dd/yyyy}", r.date16), rowIndex);
SetCell(r.string17, rowIndex);
SetCell(r.string18, rowIndex);
SetCell(r.int19, rowIndex);
SetCell(r.string20, rowIndex);
SetCell(r.string21, rowIndex);
sheetData.AppendChild(newRow);
}
private void SetCell(string val, Row theRow)
{ // a NON-SHARED string is going in to the cell
Cell theCell = new Cell();
theCell.CellValue = new CellValue(val);
theCell.DataType = new EnumValue<CellValues>(CellValues.String);
theRow.AppendChild(theCell);
}
protected void SetCell(int val, Row theRow)
{ // an int is going in to the cell
Cell theCell = new Cell();
theCell.CellValue = new CellValue(val.ToString());
theCell.DataType = new EnumValue<CellValues>(CellValues.Number);
theRow.AppendChild(theCell);
}
}
}