I'm on your side, when times get rough.

2018-10-01

[C#] Excel To DataSet with OpenXML

Filed under: Programming — Peter_KIM @ 02:56

Excel Sheet 문서의 행과 열을 DataSet 형태로 변환하는 소스 코드는 이미 몇몇의 사이트에 공개되어 있습니다.
많은 기술들 중에서 가장 좋지 않은 것이 바로, OLE 방식으로 Excel 프로그램과 직접적인 통신으로 데이터를 변환하는 것입니다. 시대가 바뀌고, 응용 프로그램의 기술이 발전한 상황에서 이런 구 시대의 기술을 이용하는 것은 매우 불합리한 경우가 대부분입니다.
OpenXML 기술을 이용하면, Office 문서들을 쉽게 프로그램 코드에서 사용할 수 있는 형태로 변환할 수 있습니다.
https://github.com/OfficeDev/Open-XML-SDK
https://docs.microsoft.com/en-us/office/open-xml/open-xml-sdk

아래의 주소에 이미 OpenXML 기술을 이용하여, Excel 문서를 DataTable 형태로 변환하는 코드가 있습니다.
https://dotnetthoughts.net/read-excel-as-datatable-using-openxml-and-c/

이 코드를 확장하고, 수정하여 Excel 문서에 있는 여러 개의 Sheet 데이터를 처리할 수 있도록 코드를 수정해 보았습니다.

public DataSet OpenExcelToDataSet(string sFileName)
{
    DataSet ds = null;
    using (SpreadsheetDocument oSpreadSheetDoc = SpreadsheetDocument.Open(sFileName, false))
    {
        WorkbookPart oWorkbookPart = oSpreadSheetDoc.WorkbookPart;
 
        OpenXmlElementList lstOpenXmlElements = oSpreadSheetDoc.WorkbookPart.Workbook.ChildElements;
        foreach (Sheets vSheets in lstOpenXmlElements.OfType<Sheets>())
        {
            ds = new DataSet();
 
            foreach (Sheet vSheet in vSheets)
            {
                DataTable dt = new DataTable();
                dt.Name = vSheet.Name;
                String vRelationId = vSheet.Id.Value;
                WorksheetPart oWorksheetPart = (WorksheetPart) oWorkbookPart.GetPartById(vRelationId);
                Worksheet oWorksheet = oWorksheetPart.Worksheet;
 
                OpenXmlElementList lstOpenXmlChildElements = oWorksheet.ChildElements;
                foreach (SheetData vSheetData in lstOpenXmlChildElements.OfType<SheetData>())
                {
                    IEnumerable<Row> enumRows = vSheetData.Descendants<Row>();
                    if (enumRows.Count() == 0)
                        continue;
                    
                    var vFirstRow = enumRows.First();
 
                    // Make Columns with first row...
                    IEnumerable <Cell> enumFirstRowCells = vFirstRow.Descendants<Cell>();
                    for (int i = 0; i < enumFirstRowCells.Count(); ++i)
                    {
                        Cell vCell = enumFirstRowCells.ElementAt(i);
                        String sCellValue = vCell.CellValue?.InnerXml;
                        if ((vCell.DataType != null)
                            && (vCell.DataType.Value == CellValues.SharedString))
                        {
                            sCellValue = oWorkbookPart.SharedStringTablePart.SharedStringTable.ChildElements[Int32.Parse(sCellValue)].InnerText;
                        }
                        dt.Columns.Add(sCellValue);
                    }
 
                    foreach (Row vRow in enumRows)
                    {
                        DataRow dtRow = dt.NewRow();
 
                        IEnumerable<Cell> enumCells = vRow.Descendants<Cell>();
                        for (int i = 0; i < enumCells.Count(); ++i)
                        {
                            Cell vCell = enumCells.ElementAt(i);
                            String sCellValue = vCell.CellValue?.InnerXml;
                            if ((vCell.DataType != null)
                                && (vCell.DataType.Value == CellValues.SharedString))
                            {
                                sCellValue = oWorkbookPart.SharedStringTablePart.SharedStringTable.ChildElements[Int32.Parse(sCellValue)].InnerText;
                            }
                            dtRow[i] = sCellValue;
                        }
                        dt.Rows.Add(dtRow);
                    }
                    dt.Rows.RemoveAt(0);
                    ds.Tables.Add(dt);
                }
            }
        }
    }
    return ds;
}

예제 프로젝트는 아래의 주소에서 내려받을 수 있습니다.
https://1drv.ms/u/s!An5hHO7t37wbhiKsWmpK7m4GemOd

[Windows] IP Setting with Command Line (BATCH)

Filed under: Programming — Peter_KIM @ 02:35
@ECHO OFF
IF '%1' == 'S' GOTO STATIC
IF '%1' == 's' GOTO STATIC
IF '%1' == 'D' GOTO DHCP
IF '%1' == 'd' GOTO DHCP
 
GOTO END
    
:DHCP
    netsh interface ipv4 set address name="Ethernet" source=dhcp
    netsh interface ipv4 set dnsserver "Ethernet" dhcp
    GOTO END
 
:STATIC
    netsh interface ipv4 set address name="Ethernet" source=static addr=192.168.100.32 mask=255.255.255.0 gateway=192.168.100.1
    netsh interface ipv4 add dnsservers "Ethernet" address=8.8.8.8 index=1
    netsh interface ipv4 add dnsservers "Ethernet" address=8.8.4.4 index=2
    GOTO END
:END

 

Create a free website or blog at WordPress.com.