2

OpenXML(SAXメソッド)を使用してExcelドキュメントを作成しようとしています。メソッドが呼び出されたら、特定のキーに対してタブがすでに作成されているかどうかを確認したいと思います。その場合は、そのタブの下部に行を追加したいと思います。特定のキーに対してタブが作成されていない場合は、次のような新しいタブを作成します。

      part = wbPart.AddNewPart<WorksheetPart>();

                        string worksheetName = row.Key[i].ToString();

                        Sheet sheet = new Sheet() { Id = document.WorkbookPart.GetIdOfPart(part), SheetId = sheetNumber, Name = worksheetName };
                        sheets.Append(sheet);

                        writer = OpenXmlWriter.Create(part);
                        writer.WriteStartElement(new Worksheet());
                        writer.WriteStartElement(new SheetData());

                        currentrow = 1;

                        string header = Header + "\t" + wrapper.GetHeaderString(3, 2, -1); //need to fix
                        WriteDataToExcel(header, currentrow, 0, writer);
                        currentrow++;


                        writer.WriteEndElement();
                        writer.WriteEndElement();
                        writer.Close();

タブがすでに作成されている場合は、次のコードを使用してシートを呼び出します。

private static WorksheetPart GetWorksheetPartByName(SpreadsheetDocument document, string sheetName)
    {
        IEnumerable<Sheet> sheets =
           document.WorkbookPart.Workbook.GetFirstChild<Sheets>().
           Elements<Sheet>().Where(s => s.Name == sheetName);

        if (sheets.Count() == 0)
        {
            // The specified worksheet does not exist.

            return null;
        }

        string relationshipId = sheets.First().Id.Value;
        WorksheetPart worksheetPart = (WorksheetPart)
             document.WorkbookPart.GetPartById(relationshipId);
        return worksheetPart;

    }

正しいワークシートパーツが返されたら、OpenXmlWriterを正しいパーツにポイントしてから行を追加することにより、新しい行を追加しようとします。

   part = GetWorksheetPartByName(document, row.Key[i].ToString());

                        writer = OpenXmlWriter.Create(part);
                        writer.WriteStartElement(part.Worksheet);
                        writer.WriteStartElement(part.Worksheet.GetFirstChild<SheetData>());
                        SheetData sheetData = part.Worksheet.GetFirstChild<SheetData>();
                        Row lastRow = sheetData.Elements<Row>().LastOrDefault();

コードは実行されますが、最終的には常に1行(最初にタブを作成したときに追加した最初の行)になります。後続の行はスプレッドシートに表示されません。

たくさんの行(50,000以上)を追加するので、毎回新しいファイルを作成して情報をコピーする必要はありません。

4

2 に答える 2

4

私の経験から、SAXメソッドを使用して(つまり、OpenXmlWriterを使用して)書くことは、新しいもの(パーツ、ワークシートなど)に最適です。OpenXmlWriter.Create()を使用する場合、これはパーツ(この場合はWorksheetPart)の元の既存のデータを上書きするようなものです。事実上、そうではありません。それは複雑です。

私の実験では、既存のデータがある場合、OpenXmlWriterを使用してデータを編集することはできません。Save()関数を使用したり、OpenXmlWriterを正しく閉じたりしても、そうではありません。何らかの理由で、SDKはあなたの努力を無視します。したがって、追加した元の1行。

50,000行を書き込む場合は、一度にすべてを書き込むのが最善です。そうすれば、SAXメソッドが役立ちます。さらに、(一度に?)1行を記述している場合、DOMメソッドと比較してSAXを使用することによる速度の利点はごくわずかです。

于 2013-01-21T12:10:57.140 に答える
0

このサイトによると、OpenXMLWriterを使用した既存のExcelでの作業:OpenXMLWriterは、既存のドキュメントではなく、新しいワークシートのみを操作できます。そのため、OpenXMLWriterを使用して既存のスプレッドシートの特定のセルに値を挿入することはできません。

既存のExcelファイル内のすべてのデータを読み取ることができ、行を追加する必要があるようです(50,000以上)openxmlwriterを使用して、古いデータと新しいデータを新しいExcelファイルに一度に書き込むことをお勧めします。DOMアプローチを使用する場合、多くの行(50,000以上)を追加した後、メモリの問題が発生する可能性があります。

于 2019-01-17T04:05:44.547 に答える