9

OpenXML を使用して ASP.NET Web サーバーから Excel ファイルを書き出そうとしています。約 2100 のレコードがあり、これを行うには約 20 ~ 30 秒かかります。速くする方法はありますか?データベースから 2100 行を取得するには、ほんの一瞬しかかかりません。それらをメモリ内で操作するのに時間がかかる理由がわかりません。

注: ExcelWriter はカスタム クラスですが、そのすべてのメソッドは、このリンクのコードから直接取得されています。 http://msdn.microsoft.com/en-us/library/cc861607.aspx

   public static MemoryStream CreateThingReport(List<Thing> things, MemoryStream template)
    {
        SpreadsheetDocument spreadsheet = SpreadsheetDocument.Open(template, true);
        WorksheetPart workSheetPart = spreadsheet.WorkbookPart.WorksheetParts.First();

        SharedStringTablePart sharedStringPart = spreadsheet.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();

        Cell cell = null;
        int index = 0;

        //create cell formatting for header text
        Alignment wrappedAlignment = new Alignment { WrapText = true };
               uint rowOffset = 2;

  foreach (Thing t in things)
        {
            //Received Date
            cell = ExcelWriter.InsertCellIntoWorksheet("A", rowOffset, workSheetPart);
            index = ExcelWriter.InsertSharedStringItem(t.CreateDate.ToShortDateString(), sharedStringPart);
            cell.CellValue = new CellValue(index.ToString());
            cell.DataType = new DocumentFormat.OpenXml.EnumValue<CellValues>(CellValues.SharedString);

            //Car Part Name
            cell = ExcelWriter.InsertCellIntoWorksheet("B", rowOffset, workSheetPart);
            index = ExcelWriter.InsertSharedStringItem(t.CarPart.Name, sharedStringPart);
            cell.CellValue = new CellValue(index.ToString());
            cell.DataType = new DocumentFormat.OpenXml.EnumValue<CellValues>(CellValues.SharedString);

  rowOffset++; 
   }

 workSheetPart.Worksheet.Save();

        spreadsheet.WorkbookPart.Workbook.Save();
        spreadsheet.Close();

        return template;
4

5 に答える 5

8

そのため、MSDN コミュニティ ドキュメントの誰かが同様のパフォーマンスへの影響に遭遇したようです。以下のコードは非常に非効率的です。誰かがハッシュ テーブルの使用を推奨しました。

私たちのソリューションでは、共有文字列の挿入を完全に削除しただけで、ダウンロード時間が 1:03 秒から 0:03 秒になりました。

//Old: (1:03)
            cell = ExcelWriter.InsertCellIntoWorksheet("A", rowOffset, workSheetPart);
            index = ExcelWriter.InsertSharedStringItem(thing.CreateDate.ToShortDateString(), sharedStringPart);
            cell.CellValue = new CellValue(index.ToString());
            cell.DataType = new DocumentFormat.OpenXml.EnumValue<CellValues>(CellValues.SharedString);

 //New: (0:03)
             cell = ExcelWriter.InsertCellIntoWorksheet("A", rowOffset, workSheetPart);
             cell.CellValue = new CellValue(thing.CreateDate.ToShortDateString());
              cell.DataType = new DocumentFormat.OpenXml.EnumValue<CellValues>(CellValues.String);

MSDN ドキュメント (遅い解決策、代わりにハッシュ テーブルを使用する必要があります)

      private static int InsertSharedStringItem(string text, SharedStringTablePart         shareStringPart)
  {
// If the part does not contain a SharedStringTable, create one.
if (shareStringPart.SharedStringTable == null)
{
    shareStringPart.SharedStringTable = new SharedStringTable();
}

int i = 0;

// Iterate through all the items in the SharedStringTable. If the text already exists, return its index.
foreach (SharedStringItem item in shareStringPart.SharedStringTable.Elements<SharedStringItem>())
{
    if (item.InnerText == text)
    {
        return i;
    }

    i++;
}

// The text does not exist in the part. Create the SharedStringItem and return its index.
shareStringPart.SharedStringTable.AppendChild(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text(text)));
shareStringPart.SharedStringTable.Save();

return i;
 }  
于 2012-05-11T15:46:15.753 に答える
5

@インターネット

文字列データ型は実際には数式用であることに注意してください。テキストには InlineString を使用する必要があります。17.18.11 ST_CellType (セル タイプ) を参照してください。

  • inlineStr (インライン文字列) - (インライン) リッチ文字列、つまり共有文字列テーブルにない文字列を含むセル。このセル タイプが使用されている場合、セル値はセルの v 要素 (c 要素) ではなく is 要素にあります。
  • str (文字列) - 数式文字列を含むセル。
于 2014-05-19T20:36:57.553 に答える
4

大きな改善点は、ループ外の Save() 関数です。

 //Save data
        shareStringPart.SharedStringTable.Save();
        worksheetPart.Worksheet.Save();

500 レコードの場合、私にとっては 10 分から 1 分に変わります。

于 2015-02-12T10:43:02.773 に答える