[英]C# Open XML SDK 2.0 Excel spreadsheet - load range of cells from string array
在.Net Windows桌面應用程序中,我能夠將字符串數據數組導入Excel電子表格中的一系列單元格中。 C#代碼如下:
using Excel = Microsoft.Office.Interop.Excel;
// Create Application, Workbook, and Worksheet
xlApp = new Microsoft.Office.Interop.Excel.Application();
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWs = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
// Move data from temp array into Excel spreadsheet.
Excel.Range c1 = (Excel.Range)xlWs.Cells[startRowNum, 1];
Excel.Range c2 = (Excel.Range)xlWs.Cells[startRowNum + myTable.Rows.Count - 1, Columns.Count];
Excel.Range range = xlWs.get_Range(c1, c2);
range.Value = tempArray;
我正在嘗試在ASP.Net網頁中重復此過程。 使用Visual Studio 2010和C#。 如何將同樣的字符串數組導入到Open XML SDK 2.0 Excel電子表格范圍的單元格中?
答案是,庫可能更易於使用。 另一種庫選擇是SpreadsheetLight 。 代碼如下所示:
SLDocument sl = new SLDocument("YourFile.xlsx");
// row 1 column 1
sl.SetCellValue(1, 1, "String1");
// row 1 column 2
sl.SetCellValue(1, 2, "String2");
sl.SaveAs("AnotherFile.xlsx");
您不必擔心設置單元格值的順序。 在內部,SpreadsheetLight在Open XML SDK上運行。 免責聲明:我寫了SpreadsheetLight。
直接使用OpenXML SDK而不是通過Excel的自動化模型,要復雜得多且容易出錯。 因此,我建議為此使用一個庫。 特別是如果您的任務變得更加復雜(例如, http : //excelpackage.codeplex.com/ )。 編輯 :可以在此處找到有關使用ExcelPackage進行類似操作的示例: http ://excelpackage.codeplex.com/wikipage?title=使用%20a%20template%20to%20create%20an%20Excel%20spreadsheet,盡管我對此一無所知與使用原始SDK相比預期的性能如何,我想ExcelPackage無論如何都在內部使用SDK,因此可能會產生一些開銷。 在這里,可能只有針對您的具體方案的度量才能提供明確的答案。
如果您想堅持使用SDK,請參考以下示例,將字符串插入Excel工作簿:
string filePath = "workbook.xlsx";
string sheetName = "Sheet1";
uint startRow = 9;
string columnName = "C";
string[] data = new string[] { "A", "B", "C" };
using (var spreadsheetDocument = SpreadsheetDocument.Open(filePath, true))
{
// Find the Id of the worksheet in question
var sheet = spreadsheetDocument.WorkbookPart.Workbook
.Sheets.Elements<Sheet>()
.Where(s => s.Name == sheetName).First();
var sheetReferenceId = sheet.Id;
// Map the Id to the worksheet part
WorksheetPart worksheetPart = (WorksheetPart)spreadsheetDocument.WorkbookPart.GetPartById(sheetReferenceId);
var sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
// Inset the data at the given location
for (uint i = 0; i < data.Length; i++)
{
uint rowNumber = startRow + i;
// Find the XML entry for row i
var row = sheetData.Elements<Row>().Where(r => r.RowIndex == rowNumber).FirstOrDefault();
if (row == null)
{
// Row does not exist yet, create it
row = new Row();
row.RowIndex = rowNumber;
// Insert the row at its correct sequential position
Row rowAfter = null;
foreach (Row otherRow in sheetData.Elements<Row>())
{
if (otherRow.RowIndex > row.RowIndex)
{
rowAfter = otherRow;
break;
}
}
if (rowAfter == null)
// New row is the last row in the sheet
sheetData.Append(row);
else
sheetData.InsertBefore(row, rowAfter);
}
// CellReferences in OpenXML are "normal" Excel cell references, e.g. D15
string cellReference = columnName + rowNumber.ToString();
// Find cell in row
var cell = row.Elements<Cell>()
.Where(c => c.CellReference == cellReference)
.FirstOrDefault();
if (cell == null)
{
// Cell does not exist yet, create it
cell = new Cell();
cell.CellReference = new StringValue(cellReference);
// The cell must be in the correct position (e.g. column B after A)
// Note: AA must be after Z, so a normal string compare is not sufficient
Cell cellAfter = null;
foreach (Cell otherCell in row.Elements<Cell>())
{
// This is ugly, but somehow the row number must be stripped from the
// cell reference for comparison
string otherCellColumn = otherCell.CellReference.Value;
otherCellColumn = otherCellColumn.Remove(otherCellColumn.Length - rowNumber.ToString().Length);
// Now compare first to length and then alphabetically
if (otherCellColumn.Length > columnName.Length ||
string.Compare(otherCellColumn, columnName, true) > 0)
{
cellAfter = otherCell;
break;
}
}
if (cellAfter == null)
// New cell is last cell in row
row.Append(cell);
else
row.InsertBefore(cell, cellAfter);
}
// Note: This is the most simple approach.
// Normally Excel itself will store the string as a SharedString,
// which is more difficult to implement. The only drawback of using
// this approach though, is that the cell might have been the only
// reference to its shared string value, which is not deleted from the
// list here.
cell.DataType = CellValues.String;
cell.CellValue = new CellValue(data[i]);
}
}
請注意,此示例並不完美,因為它根本沒有考慮復雜的情況(例如,樣式,打印頁邊距,合並的單元格...)。 對於生產用途,您可能希望將某些功能提取到方法中(例如,將行或單元格插入正確的位置),或者甚至全部提取到類中(例如,按正確順序比較單元格引用的部分)。
編輯 :使用SDK而不是通過自動化模型的性能要好得多(這可能是SDK的第二個巨大優勢,第一個是您不需要安裝Excel。) 如果您仍然看到性能瓶頸,請參考以下改進建議:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.