如何使用开放式XML C#将excel行和表特定读取到数据表中?
答案 0 :(得分:0)
好的,你需要实现两件事:
以下是按名称获取工作表对象的代码段,以及按地址获取单元格对象:
Private Function GetWorksheet(ByRef document As SpreadsheetDocument, ByVal worksheetName As String) As Worksheet
Dim sheets As IEnumerable(Of Sheet) = document.WorkbookPart.Workbook.Descendants(Of Sheet)().Where(Function(s) s.Name = worksheetName)
If (sheets.Count = 0) Then
' The specified worksheet does not exist.
Return Nothing
End If
Dim worksheetPart As WorksheetPart = CType(document.WorkbookPart.GetPartById(sheets.First.Id), WorksheetPart)
Return worksheetPart.Worksheet
End Function
Private Function GetCellByAdrress(ByRef ws As Worksheet, addressName As String) As Cell
Dim sheetData As SheetData = ws.GetFirstChild(Of SheetData)()
Dim cell As Cell = Nothing
Dim rowNumber As UInt32 = GetRowIndex(addressName)
Dim row As Row = GetRow(sheetData, rowNumber)
' If the cell you need already exists, return it.
' If there is not a cell with the specified column name, insert one.
Dim refCell As Cell = row.Elements(Of Cell)().Where(Function(c) c.CellReference.Value = addressName).FirstOrDefault()
'refCell.Remove()
If refCell IsNot Nothing Then
cell = refCell
Else
cell = CreateCell(row, addressName)
End If
Return cell
End Function
Private Function GetRowIndex(ByVal address As String) As UInt32
Dim rowPart As String
Dim l As UInt32
Dim result As UInt32 = 0
For i As Integer = 0 To address.Length - 1
If UInt32.TryParse(address.Substring(i, 1), l) Then
rowPart = address.Substring(i, address.Length - i)
If UInt32.TryParse(rowPart, l) Then
result = l
Exit For
End If
End If
Next
Return result
End Function
Private Function GetRow(ByRef wsData As SheetData, ByVal rowIndex As UInt32) As Row
Dim row = wsData.Elements(Of Row)().Where(Function(r) r.RowIndex.Value = rowIndex).FirstOrDefault()
If row Is Nothing Then
row = New Row()
row.RowIndex = rowIndex
wsData.Append(row)
End If
Return row
End Function
Private Function CreateCell(row As Row, address As [String]) As Cell
Dim cellResult As Cell
Dim refCell As Cell = Nothing
' Cells must be in sequential order according to CellReference.
' Determine where to insert the new cell.
For Each cell As Cell In row.Elements(Of Cell)()
If String.Compare(cell.CellReference.Value, address, True) > 0 Then
refCell = cell
Exit For
End If
Next
cellResult = New Cell()
cellResult.CellReference = address
row.InsertBefore(cellResult, refCell)
Return cellResult
End Function
使用函数的代码:
Function ReadCellValue(address as string, worksheetName as string)
dim worksheet = GetWorksheet(docObj, worksheetName)
dim cellObj as Cell = GetCellByAdrress(worksheet, "B31")
if cellObj isnot Nothing
dim value = cellObj.CellValue
end if
End Function
希望这会有所帮助。如果有任何歧义,请告诉我。
答案 1 :(得分:0)
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
private void readExcel(Stream file)
{
String sheetName = "Sheet2";
String delimiter = ";";
int startColumn = 2;// 2 convert to B
int endColumn = 6; // read until column 6
int startRow = 31; // start read from row 31
String columnRequest = "Request";
DataTable dt = new DataTable();
dt.Columns.Add(columnRequest);
DataRow dr;
String stringRequest = "";
String stringNopek = "Init";
String value = "";
int indexRow = 0;
using (SpreadsheetDocument myDoc = SpreadsheetDocument.Open(file, false))
{
WorkbookPart wbPart = myDoc.WorkbookPart;
indexRow = startRow;
while (!stringNopek.Equals(""))
{
stringNopek = getCellValue(GetExcelColumnName(startColumn) + indexRow.ToString(), sheetName, wbPart).Trim();
stringRequest = stringNopek;
if (!stringNopek.Equals(""))
{
dr = dt.NewRow();
for (int i = startColumn + 1; i <= endColumn; i++)
{
value = getCellValue(GetExcelColumnName(i) + indexRow.ToString(), sheetName, wbPart).Trim();
stringRequest += delimiter + value;
}
dr[columnRequest] = stringRequest;
dt.Rows.Add(dr);
}
indexRow++;
}
}
Session["DataTableRequest"] = dt;
string output = "";
for (int i = 0; i < dt.Rows.Count; i++)
{
output = output + dt.Rows[i][columnRequest].ToString();
output += (i < dt.Rows.Count) ? Environment.NewLine : string.Empty;
}
}
private string GetExcelColumnName(int columnNumber)
{
int dividend = columnNumber;
string columnName = String.Empty;
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
dividend = (int)((dividend - modulo) / 26);
}
return columnName;
}
private int ColumnIndex(string reference)
{
int ci = 0;
reference = reference.ToUpper();
for (int ix = 0; ix < reference.Length && reference[ix] >= 'A'; ix++)
ci = (ci * 26) + ((int)reference[ix] - 64);
return ci;
}
private String getCellValue(String cellReference, String sheetName, WorkbookPart wbPart)
{
Sheet theSheet = wbPart.Workbook.Descendants<Sheet>().
Where(s => s.Name == sheetName).FirstOrDefault();
if (theSheet == null)
{
throw new ArgumentException(sheetName);
}
WorksheetPart wsPart =
(WorksheetPart)(wbPart.GetPartById(theSheet.Id));
Cell theCell = wsPart.Worksheet.Descendants<Cell>().
Where(c => c.CellReference == cellReference).FirstOrDefault();
String value = "";
if (theCell != null)
{
if (theCell.CellValue != null)
{
value = theCell.CellValue.Text;
}
else
{
value = value = theCell.InnerText;
}
if (theCell.DataType != null)
{
switch (theCell.DataType.Value)
{
case CellValues.SharedString:
var stringTable =
wbPart.GetPartsOfType<SharedStringTablePart>()
.FirstOrDefault();
if (stringTable != null)
{
value =
stringTable.SharedStringTable
.ElementAt(int.Parse(value)).InnerText;
}
break;
case CellValues.Boolean:
switch (value)
{
case "0":
value = "FALSE";
break;
default:
value = "TRUE";
break;
}
break;
}
}
}
return value;
}
protected void UploadControl_FileUploadComplete(object sender, FileUploadCompleteEventArgs e){
Stream strm = e.UploadedFile.FileContent;
readExcel(strm);
}