182列のスプレッドシートドキュメントがあります。スプレッドシートデータをタブごとにデータテーブルに配置する必要がありますが、各タブからデータを追加しているときに、タブ名を確認し、データテーブルの列にタブ名を追加する必要があります。 。
これが私がデータテーブルを設定する方法です。
次に、ブックをループしてsheetData
オブジェクトにドリルダウンし、各行と列をウォークスルーして、セルデータを取得します。
DataTable dt = new DataTable();
for (int i = 0; i <= col.GetUpperBound(0); i++)
{
try
{
dt.Columns.Add(new DataColumn(col[i].ToString(), typeof(string)));
}
catch (Exception e)
{
MessageBox.Show("Uploader Error" + e.ToString());
return null;
}
}
dt.Columns.Add(new DataColumn("SheetName", typeof(string)));
ただし、データテーブルに使用する文字列配列の最後に、タブ名を追加する必要があります。 Open XMLでシートをループしているときに、タブ名を確認するにはどうすればよいですか?
これまでの私のコードは次のとおりです。
using (SpreadsheetDocument spreadSheetDocument =
SpreadsheetDocument.Open(Destination, false))
{
WorkbookPart workbookPart = spreadSheetDocument.WorkbookPart;
Workbook workbook = spreadSheetDocument.WorkbookPart.Workbook;
Sheets sheets =
spreadSheetDocument
.WorkbookPart
.Workbook
.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>();
OpenXmlElementList list = sheets.ChildElements;
foreach (WorksheetPart worksheetpart in workbook.WorkbookPart.WorksheetParts)
{
Worksheet worksheet = worksheetpart.Worksheet;
foreach (SheetData sheetData in worksheet.Elements<SheetData>())
{
foreach (Row row in sheetData.Elements())
{
string[] thisarr = new string[183];
int index = 0;
foreach (Cell cell in row.Elements())
{
thisarr[(index)] = GetCellValue(spreadSheetDocument, cell);
index++;
}
thisarr[182] = ""; //need to add tabname here
if (thisarr[0].ToString() != "")
{
dt.Rows.Add(thisarr);
}
}
}
}
}
return dt;
注:以前は、「リスト」のInnerXMLプロパティからタブ名を取得していました。
OpenXmlElementList list = sheets.ChildElements;
ただし、スプレッドシートをループしているときに、タブ名が正しい順序で取得されないことに気付きました。
シート名は、Excelファイルの各ワークシートに対応する要素WorkbookPart
の子を持つSheets
要素のSheet
に格納されます。あなたがしなければならないのは、そのSheets
要素から正しいインデックスを取得することだけであり、それはあなたがあなたのループにいるSheet
になります。以下にコードスニペットを追加して、必要な処理を実行します。
int sheetIndex = 0;
foreach (WorksheetPart worksheetpart in workbook.WorkbookPart.WorksheetParts)
{
Worksheet worksheet = worksheetpart.Worksheet;
// Grab the sheet name each time through your loop
string sheetName = workbookPart.Workbook.Descendants<Sheet>().ElementAt(sheetIndex).Name;
foreach (SheetData sheetData in worksheet.Elements<SheetData>())
{
...
}
sheetIndex++;
}
WorksheetPartに対応するシートを取得するための便利なヘルパーメソッドを次に示します。
public static Sheet GetSheetFromWorkSheet
(WorkbookPart workbookPart, WorksheetPart worksheetPart)
{
string relationshipId = workbookPart.GetIdOfPart(worksheetPart);
IEnumerable<Sheet> sheets = workbookPart.Workbook.Sheets.Elements<Sheet>();
return sheets.FirstOrDefault(s => s.Id.HasValue && s.Id.Value == relationshipId);
}
次に、シートName-propertyから名前を取得できます。
Sheet sheet = GetSheetFromWorkSheet(myWorkbookPart, myWorksheetPart);
string sheetName = sheet.Name;
...これは、参照される「タブ名」OPになります。
レコードの場合、反対の方法は次のようになります。
public static Worksheet GetWorkSheetFromSheet(WorkbookPart workbookPart, Sheet sheet)
{
var worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);
return worksheetPart.Worksheet;
}
...これで、次のメソッドを追加することもできます。
public static IEnumerable<KeyValuePair<string, Worksheet>> GetNamedWorksheets
(WorkbookPart workbookPart)
{
return workbookPart.Workbook.Sheets.Elements<Sheet>()
.Select(sheet => new KeyValuePair<string, Worksheet>
(sheet.Name, GetWorkSheetFromSheet(workbookPart, sheet)));
}
これで、名前を含むすべてのワークシートを簡単に列挙できます。
必要に応じて、名前ベースのルックアップ用にすべてを辞書に入れます。
IDictionary<string, WorkSheet> wsDict = GetNamedWorksheets(myWorkbookPart)
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
...または名前で特定のシートを1つだけ必要な場合:
public static Sheet GetSheetFromName(WorkbookPart workbookPart, string sheetName)
{
return workbookPart.Workbook.Sheets.Elements<Sheet>()
.FirstOrDefault(s => s.Name.HasValue && s.Name.Value == sheetName);
}
(次に、GetWorkSheetFromSheet
を呼び出して、対応するワークシートを取得します。)
Using spreadsheetDocument As SpreadsheetDocument = spreadsheetDocument.Open("D:\Libro1.xlsx", True)
Dim workbookPart As WorkbookPart = spreadsheetDocument.WorkbookPart
workbookPart.Workbook.Descendants(Of Sheet)()
Dim worksheetPart As WorksheetPart = workbookPart.WorksheetParts.Last
Dim text As String
For Each Sheet As Sheet In spreadsheetDocument.WorkbookPart.Workbook.Sheets
Dim sName As String = Sheet.Name
Dim sID As String = Sheet.Id
Dim part As WorksheetPart = workbookPart.GetPartById(sID)
Dim actualSheet As Worksheet = part.Worksheet
Dim sheetData As SheetData = part.Worksheet.Elements(Of SheetData)().First
For Each r As Row In sheetData.Elements(Of Row)()
For Each c As Cell In r.Elements(Of Cell)()
text = c.CellValue.Text
Console.Write(text & " ")
Next
Next
Next
End Using
Console.Read()
worksheet.GetAttribute("name","").Value