OpenXml을 이용하여 엑셀 파일의 빈 셀 읽기
OpenXml을 이용하면 처음으로 부딪치게 되는 문제가 바로 빈 셀입니다.
저는 이 문제를 DataTable을 이용하여 해결하였습니다.
첫 번째 Row가 제목 열이라 생각하고 첫 번째의 Row 정보를 DataTable의 컬럼으로 만들고,
Data에 해당하는 Row를 DataTable에 입력하는 형태로 진행하였습니다.
DataTable에 입력하는 방식은 CellType.CellReference의 값을 읽어서 처리하는 형태입니다.
아래는 전체 코드입니다.
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data; using System.IO; using System.Text.RegularExpressions; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Spreadsheet; using DocumentFormat.OpenXml.Wordprocessing; namespace WebApplication1.OpenXml { public partial class ReadExcelData : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { using (SpreadsheetDocument myDoc = SpreadsheetDocument.Open(@"C:\test.xlsx", true)) { IEnumerable<Sheet> sheets = myDoc.WorkbookPart.Workbook.Descendants<Sheet>(); WorksheetPart worksheetPart1 = myDoc.WorkbookPart.GetPartById(sheets.First().Id) as WorksheetPart; Worksheet sheet = worksheetPart1.Worksheet; IEnumerable<Row> datarow = from row in sheet.Descendants<Row>() where row.RowIndex > 0 select row; DataTable dt = new DataTable("test"); int i = 0; foreach (Row row in datarow) { if (i == 0) { foreach (Cell cell in row.Descendants<Cell>()) { dt.Columns.Add(new DataColumn(GetColumnName(cell.CellReference), typeof(string))); } } else { DataRow dr = dt.NewRow(); foreach (Cell cell in row.Descendants<Cell>()) { dr[GetColumnName(cell.CellReference)] = GetCellValue(myDoc, cell, myDoc); } dt.Rows.Add(dr); } i++; } dt.WriteXml(@"C:\test\test11.xml"); } } private string GetColumnName(string cellReference) { Regex regex = new Regex("[A-Za-z]+"); Match match = regex.Match(cellReference); return match.Value; } private string GetCellValue(SpreadsheetDocument document, Cell cell, SpreadsheetDocument myDoc) { SharedStringTablePart stringTablePart = document.WorkbookPart.SharedStringTablePart; string value = cell.CellValue != null ? cell.CellValue.InnerXml : String.Empty; if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString) return stringTablePart.SharedStringTable.ChildElements[Int32.Parse(value)].InnerText; else if (cell.StyleIndex.InnerText.Equals("1")) { string strDate = String.Empty; DateTime cellDate = DateTime.FromOADate(Convert.ToDouble(cell.CellValue.InnerText)); if (cellDate != null) strDate = cellDate.ToString("yyyy-MM-dd"); return strDate; } else return value; } } }
이상입니다.
감사합니다~
'CSharp > Development' 카테고리의 다른 글
C# 금주의 시작일과 끝일 가져오기 (0) | 2011.08.03 |
---|---|
Dropdownlist, Listbox Sorting With Linq (0) | 2011.07.19 |
Reading dates from OpenXml Excel files (0) | 2011.05.12 |
.NET Framework 버전 별 새로운 기능 (0) | 2011.03.23 |
Visual Studio 2010 and .NET Framework 4 Training Kit (2) | 2011.01.19 |