Excel 파일에서 xml 읽기 열기
제 프로젝트에 openXml sdk 2.5를 구현하고 싶습니다.이 링크에서 모든 작업을 수행합니다.
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System.IO.Packaging;
static void Main(string[] args)
{
String fileName = @"C:\OPENXML\BigData.xlsx";
// Comment one of the following lines to test the method separately.
ReadExcelFileDOM(fileName); // DOM
//ReadExcelFileSAX(fileName); // SAX
}
// The DOM approach.
// Note that the code below works only for cells that contain numeric values.
//
static void ReadExcelFileDOM(string fileName)
{
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(fileName, false))
{
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
string text;
int rowCount= sheetData.Elements<Row>().Count();
foreach (Row r in sheetData.Elements<Row>())
{
foreach (Cell c in r.Elements<Cell>())
{
text = c.CellValue.Text;
Console.Write(text + " ");
}
}
Console.WriteLine();
Console.ReadKey();
}
}
하지만 난 아무 말도 안 할거야.루프에 들어가지 않았습니다.주의: 컴퓨터 openXml sdk 2.5도 셋업했습니다.
그리고 아래 코드는 숫자 값을 위한 작업입니다.문자열 값의 경우 0 1 2 ...가 됩니다.
private static void Main(string[] args)
{
var filePath = @"C:/OPENXML/BigData.xlsx";
using (var document = SpreadsheetDocument.Open(filePath, false))
{
var workbookPart = document.WorkbookPart;
var workbook = workbookPart.Workbook;
var sheets = workbook.Descendants<Sheet>();
foreach (var sheet in sheets)
{
var worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);
var sharedStringPart = workbookPart.SharedStringTablePart;
//var values = sharedStringPart.SharedStringTable.Elements<SharedStringItem>().ToArray();
string text;
var rows = worksheetPart.Worksheet.Descendants<Row>();
foreach (var row in rows)
{
Console.WriteLine();
int count = row.Elements<Cell>().Count();
foreach (Cell c in row.Elements<Cell>())
{
text = c.CellValue.InnerText;
Console.Write(text + " ");
}
}
}
}
Console.ReadLine();
}
당신의 접근법은 "루프 안으로" 들어섰다는 점에서 제게는 효과가 있는 것 같았습니다.다만, 다음과 같은 것을 시험해 볼 수도 있습니다.
void Main()
{
string fileName = @"c:\path\to\my\file.xlsx";
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (SpreadsheetDocument doc = SpreadsheetDocument.Open(fs, false))
{
WorkbookPart workbookPart = doc.WorkbookPart;
SharedStringTablePart sstpart = workbookPart.GetPartsOfType<SharedStringTablePart>().First();
SharedStringTable sst = sstpart.SharedStringTable;
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
Worksheet sheet = worksheetPart.Worksheet;
var cells = sheet.Descendants<Cell>();
var rows = sheet.Descendants<Row>();
Console.WriteLine("Row count = {0}", rows.LongCount());
Console.WriteLine("Cell count = {0}", cells.LongCount());
// One way: go through each cell in the sheet
foreach (Cell cell in cells)
{
if ((cell.DataType != null) && (cell.DataType == CellValues.SharedString))
{
int ssid = int.Parse(cell.CellValue.Text);
string str = sst.ChildElements[ssid].InnerText;
Console.WriteLine("Shared string {0}: {1}", ssid, str);
}
else if (cell.CellValue != null)
{
Console.WriteLine("Cell contents: {0}", cell.CellValue.Text);
}
}
// Or... via each row
foreach (Row row in rows)
{
foreach (Cell c in row.Elements<Cell>())
{
if ((c.DataType != null) && (c.DataType == CellValues.SharedString))
{
int ssid = int.Parse(c.CellValue.Text);
string str = sst.ChildElements[ssid].InnerText;
Console.WriteLine("Shared string {0}: {1}", ssid, str);
}
else if (c.CellValue != null)
{
Console.WriteLine("Cell contents: {0}", c.CellValue.Text);
}
}
}
}
}
}
filestream 접근방식을 사용하여 워크북을 열었습니다.이 접근방식을 사용하면 워크북을 공유 액세스로 열 수 있기 때문에 동시에 Excel에서 열 수 있습니다.스프레드시트Open(... 메서드는 워크북이 다른 곳에서 열려 있으면 작동하지 않습니다.
아마 그래서 당신의 코드가 작동하지 않았던 것 같아요.
또한 필요에 따라 SharedStringTable을 사용하여 셀텍스트를 취득하는 것도 주의해 주십시오.
2018-07-11 편집:
이 게시물은 아직 표를 얻고 있기 때문에 많은 경우 Closed X를 사용하는 것이 훨씬 더 쉬울 수 있다는 점도 지적해야 합니다.ML을 사용하여 워크북을 조작/읽기/편집할 수 있습니다.문서의 예는 매우 사용하기 쉽고 코딩은 내 경험상 매우 간단합니다.문제가 될 수도 있고 그렇지 않을 수도 있는 모든 Excel 기능(INDEX 및 MATCH 등)을 구현하지는 않습니다.[어차피 OpenXML에서 INDEX와 MATCH를 다루려고 하는 것은 아닙니다]
저는 OP와 같은 문제가 있어서 위의 답변이 통하지 않았습니다.
이것이 문제인 것 같습니다.Excel로 문서를 작성하면 기본적으로 3개의 시트가 있으며 Sheet1의 행 데이터가 있는 워크시트 부품은 첫 번째가 아닌 마지막 워크시트 부품 요소가 됩니다.
나는 문서용 시계를 놓아 이것을 알아냈다.워크북 파트Visual Studio에서 워크시트부품, 결과를 확장한 다음 HasChildren = true인 SheetData 개체를 찾을 때까지 모든 하위 요소를 살펴봅니다.
이것을 시험해 보세요.
// open the document read-only
SpreadSheetDocument document = SpreadsheetDocument.Open(filePath, false);
SharedStringTable sharedStringTable = document.WorkbookPart.SharedStringTablePart.SharedStringTable;
string cellValue = null;
foreach (WorksheetPart worksheetPart in document.WorkbookPart.WorksheetParts)
{
foreach (SheetData sheetData in worksheetPart.Worksheet.Elements<SheetData>())
{
if (sheetData.HasChildren)
{
foreach (Row row in sheetData.Elements<Row>())
{
foreach (Cell cell in row.Elements<Cell>())
{
cellValue = cell.InnerText;
if (cell.DataType == CellValues.SharedString)
{
Console.WriteLine("cell val: " + sharedStringTable.ElementAt(Int32.Parse(cellValue)).InnerText);
}
else
{
Console.WriteLine("cell val: " + cellValue);
}
}
}
}
}
}
document.Close();
Large Excel 읽기 : openxml에는 DOM과 SAX의 두 가지 접근 방식이 있습니다.DOM은 전체 xml 콘텐츠(Excel 파일)를 메모리에 로드하기 때문에 RAM 리소스를 더 많이 소비하지만 강력한 유형 접근 방식을 사용합니다.반면 SAX는 이벤트 베이스 해석입니다.자세한 내용은 이쪽
따라서 큰 엑셀파일을 마주하고 있다면 SAX를 사용하는 것이 좋습니다.
아래 코드 샘플은 SAX 접근 방식을 사용하며 Excel 파일 판독에서 두 가지 중요한 시나리오를 처리합니다.
- open xml은 빈 셀을 건너뛰기 때문에 데이터셋이 치환 및 잘못된 인덱스에 직면하게 됩니다.
- 빈 행도 건너뛰어야 합니다.
이 함수는 셀의 정확한 실제 인덱스를 반환하고 첫 번째 시나리오를 처리합니다.여기서부터
private static int CellReferenceToIndex(Cell cell)
{
int index = 0;
string reference = cell.CellReference.ToString().ToUpper();
foreach (char ch in reference)
{
if (Char.IsLetter(ch))
{
int value = (int)ch - (int)'A';
index = (index == 0) ? value : ((index + 1) * 26) + value;
}
else
return index;
}
return index;
}
엑셀 색소폰 접근 방식을 읽는 코드.
//i want to import excel to data table
dt = new DataTable();
using (SpreadsheetDocument document = SpreadsheetDocument.Open(path, false))
{
WorkbookPart workbookPart = document.WorkbookPart;
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
OpenXmlReader reader = OpenXmlReader.Create(worksheetPart);
//row counter
int rcnt = 0;
while (reader.Read())
{
//find xml row element type
//to understand the element type you can change your excel file eg : test.xlsx to test.zip
//and inside that you may observe the elements in xl/worksheets/sheet.xml
//that helps to understand openxml better
if (reader.ElementType == typeof(Row))
{
//create data table row type to be populated by cells of this row
DataRow tempRow = dt.NewRow();
//***** HANDLE THE SECOND SENARIO*****
//if row has attribute means it is not a empty row
if (reader.HasAttributes)
{
//read the child of row element which is cells
//here first element
reader.ReadFirstChild();
do
{
//find xml cell element type
if (reader.ElementType == typeof(Cell))
{
Cell c = (Cell)reader.LoadCurrentElement();
string cellValue;
int actualCellIndex = CellReferenceToIndex(c);
if (c.DataType != null && c.DataType == CellValues.SharedString)
{
SharedStringItem ssi = workbookPart.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(int.Parse(c.CellValue.InnerText));
cellValue = ssi.Text.Text;
}
else
{
cellValue = c.CellValue.InnerText;
}
//if row index is 0 its header so columns headers are added & also can do some headers check incase
if (rcnt == 0)
{
dt.Columns.Add(cellValue);
}
else
{
// instead of tempRow[c.CellReference] = cellValue;
tempRow[actualCellIndex] = cellValue;
}
}
}
while (reader.ReadNextSibling());
//if its not the header row so append rowdata to the datatable
if (rcnt != 0)
{
dt.Rows.Add(tempRow);
}
rcnt++;
}
}
}
}
모든 것이 승인된 답변으로 설명되어 있습니다.
입니다.
public static string GetCellText(this Cell cell, in SharedStringTable sst)
{
if (cell.CellValue is null)
return string.Empty;
if ((cell.DataType is not null) &&
(cell.DataType == CellValues.SharedString))
{
int ssid = int.Parse(cell.CellValue.Text);
return sst.ChildElements[ssid].InnerText;
}
return cell.CellValue.Text;
}
언급URL : https://stackoverflow.com/questions/23102010/open-xml-reading-from-excel-file
'source' 카테고리의 다른 글
키를 누를 때 텍스트 상자 바인딩 (0) | 2023.04.19 |
---|---|
비어 있지 않은 기존 디렉토리를 Git 작업 디렉토리로 변환하고 파일을 원격 저장소에 푸시하는 방법 (0) | 2023.04.19 |
Excel: 현재 Excel 시트를 그대로 두지 않고 워크시트를 CSV 파일로 내보낼 수 있는 매크로 (0) | 2023.04.19 |
배치 스크립트를 통해 프로세스가 실행 중인지 확인하는 방법 (0) | 2023.04.19 |
CASE 문을 사용하여 sql server 2005의 레코드를 갱신하고 싶다. (0) | 2023.04.19 |