2017-09-07 365 views
0

私はあなたの助けをお願いします。私は、Excelファイルを読み込んでワークシートを新しいスプレッドシートにコピーするプロセスを作成しています。CSharp DocumentFormat.OpenXMLとExcel - あるスプレッドシートから別のスプレッドシートにワークシートのデータをコピーする(コードあり)

私はDocumentFormat.OpenXMLを使用して新しいスプレッドシートを作成してから、各Excelスプレッドシートをループしてワークシートをコピーします。

プロダクションサーバーでプロセスを実行し、サーバー上のWord/Excelライブラリ(Interopライブラリ)を使用する必要があるため、DocumentFormatを使用しています。

問題は、データをコピーしていないことです。スプレッドシートのタブ名がコピーされます。私は、現在のExcelファイル内の新しいスプレッドシートに新しいワークシートを作成することができます。 Excelスプレッドシートを開いたとき、アプリケーションからエラーメッセージが表示されました。

"'Test.xlsx'の内容に問題が見つかりました。できるだけリカバリを試みますか?このブックのソースを信頼する場合は、[はい]をクリックします。

[はい]をクリックしてスプレッドシートを回復しました。それはスプレッドシートのワークシート名を持っています。テストとして、Bob、Martin、Trevorのようなワークシートの名前を変更しました。このプロセスは、ワークシートの名前を新しいスプレッドシートにコピーしました。だから私はワークシートにアクセスすることができます。何らかの理由で、内部にデータをコピーしていません。

私のコードは以下のとおりです。問題を再現する必要がある場合は、Visual StudioプロジェクトにDocumentFormat.OpenXML(nuget)を用意し、OpenXML SDK 2.5をインストールする必要があります。

DocumentFormat.OpenXML(nugetから)

https://www.nuget.org/packages/DocumentFormat.OpenXml/

のOpenXML SDK 2.5

https://www.microsoft.com/en-gb/download/details.aspx?id=30425

は、ここで私は私のコードの先頭に使用してきました名前空間です。

名前空間

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using DocumentFormat.OpenXml.Packaging; 
using DocumentFormat.OpenXml.Wordprocessing; 
using DocumentFormat.OpenXml; 
using System.IO; 
using ExcelDataReader; 

テスト機能 - Excelファイルをマージします。 "C:\ lab \ excel"ディレクトリからすべてのExcelファイルを取得します。 「C:\ lab \」に「Test.xlsx」という新しいスプレッドシートが作成されます。

private static void mergeExcelFiles() 
     { 
      string mergeFilePath = "C:\\lab\\Test.xlsx"; 
      string dirPath = "C:\\lab\\excel"; 
      string[] files = System.IO.Directory.GetFiles(dirPath, "*.xlsx"); 

      // delete file 
      try 
      { 
       System.IO.File.Delete(mergeFilePath); 
      } catch (Exception ex) 
      { 
       Console.WriteLine("Can't delete file. Ex: {0}", ex.Message); 
      }    

      // CREATE SPREADSHEET 
      using (SpreadsheetDocument document = SpreadsheetDocument.Create(mergeFilePath, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook)) 
      { 
       int sheetID = 1; 

       WorkbookPart workbookPart = document.AddWorkbookPart(); 
       workbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook(); 

       WorksheetPart worksheetPart = worksheetPart = workbookPart.AddNewPart<DocumentFormat.OpenXml.Packaging.WorksheetPart>(); 
       DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets(); 

       workbookPart.Workbook.Sheets = sheets; 

       System.Diagnostics.Debug.WriteLine("Document: Before - How many worksheets?: " + document.WorkbookPart.WorksheetParts.Count()); 

       foreach (var doc in files) 
       { 
        string fullDocumentPath = doc; 

        // CHECK IF FILE EXISTS 
        if (!System.IO.File.Exists(fullDocumentPath)) 
        { 
         continue; 
        } 

        // CREATE WORKSHEETS 
        using (DocumentFormat.OpenXml.Packaging.SpreadsheetDocument tempSpreadsheet = DocumentFormat.OpenXml.Packaging.SpreadsheetDocument.Open(fullDocumentPath, true)) 
        { 
         WorkbookPart tempWorkbookPart = tempSpreadsheet.GetPartsOfType<WorkbookPart>().FirstOrDefault(); 
         DocumentFormat.OpenXml.Spreadsheet.Workbook tempWorkbook = tempWorkbookPart.Workbook; 

         DocumentFormat.OpenXml.Spreadsheet.Sheet tempSheet = tempWorkbook.Sheets.FirstOrDefault() as DocumentFormat.OpenXml.Spreadsheet.Sheet; 

         if (tempSheet == null) 
         { 
          continue; 
         } 

         tempSheet.SheetId = (uint) sheetID; 

         workbookPart.Workbook.Sheets.AppendChild(tempSheet.CloneNode(true)); 
         workbookPart.Workbook.Save(); 

         sheetID += 1; 
        } 

       } 

       document.Save(); 

       System.Diagnostics.Debug.WriteLine("Document: After - How many worksheets?: " + document.WorkbookPart.WorksheetParts.Count()); 

      } 

     } 

スプレッドシート内のデータを新しいスプレッドシートにコピーされていない理由を誰もがアドバイスしてくださいことはできますか?

答えて

0

あなたのコードでは、Excelファイル名を取得し、文字列配列に格納してから、そのExcelファイルを削除しようとしています。スプレッドシート文書を作成し、削除しようとしているのと同じmergeFilePathとして保存しようとします。

説明に基づいて、既にディレクトリのどこかに保存されているテンプレートからExcelファイルをコピーしてコピーし、Excelファイルにいくつかの変更を加える必要がありました。コードを簡略化しました:

public static void mergeExcelFiles() 
    { 
     string template = @"Template.xlsx"; // look in your bin folder 
     string fileName = @"Test.xlsx"; 
     File.Copy(template, fileName, true); 

     using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, true)) 
     { 
      // Instatiate new SheetData 
      SheetData sheetData = new SheetData(); 
      // Instatiate WorkbookPart from SpreadsheetDocument 
      WorkbookPart workbookPart = document.WorkbookPart; 
      // Get the (first)worksheet 
      //Sheet theSheet = workbookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == "Sheet1").FirstOrDefault(); 
      Sheet theSheet = workbookPart.Workbook.Descendants<Sheet>().First(); 
      if (theSheet != null) 
      { 
       sheetData = ((WorksheetPart)workbookPart.GetPartById(theSheet.Id)).Worksheet.GetFirstChild<SheetData>(); 
      } 

      Row row = new Row(); 
      Cell cell = new Cell(); 
      cell.DataType = CellValues.InlineString; 
      cell.CellReference = "A2"; 
      Text text = new Text("Some text"); 
      InlineString inlineString = new InlineString(text); 
      cell.AppendChild(inlineString); 
      row.RowIndex = (UInt32)2; 
      row.AppendChild(cell); 
      // Append new row to SheetData 
      sheetData.AppendChild(row); 

      workbookPart.Workbook.Save(); 
     } 
    } 
関連する問題