source

c#의 Open Xml SDK를 사용하여 DataTable을 Excel로 내보내기

lovecheck 2023. 4. 17. 21:58
반응형

c#의 Open Xml SDK를 사용하여 DataTable을 Excel로 내보내기

프로그램에서 일부 데이터와 DataTable을 Excel 파일(템플릿)로 내보낼 수 있습니다.템플릿에서 일부 플레이스 홀더에 데이터를 삽입합니다.아주 잘 작동하지만 DataTable도 삽입해야 하는데...샘플 코드:

using (Stream OutStream = new MemoryStream())
{
    // read teamplate
    using (var fileStream = File.OpenRead(templatePath))
        fileStream.CopyTo(OutStream);

    // exporting
    Exporting(OutStream);
         
    // to start
    OutStream.Seek(0L, SeekOrigin.Begin);
            
    // out
    using (var resultFile = File.Create(resultPath))
        OutStream.CopyTo(resultFile);

다음 내보내기 방법

private void Exporting(Stream template)
{
    using (var workbook = SpreadsheetDocument.Open(template, true, new OpenSettings                          { AutoSave = true }))
    {
        // Replace shared strings
        SharedStringTablePart sharedStringsPart = workbook.WorkbookPart.SharedStringTablePart;
        IEnumerable<Text> sharedStringTextElements = sharedStringsPart.SharedStringTable.Descendants<Text>();
           
        DoReplace(sharedStringTextElements);
        // Replace inline strings
        IEnumerable<WorksheetPart> worksheetParts = workbook.GetPartsOfType<WorksheetPart>();
          
        foreach (var worksheet in worksheetParts)
        {
            DoReplace(worksheet.Worksheet.Descendants<Text>());
        }

        int z = 40;
        foreach (System.Data.DataRow row in ExcelWorkXLSX.ToOut.Rows)
        {
            for (int i = 0; i < row.ItemArray.Count(); i++)
            { 
                ExcelWorkXLSX.InsertText(workbook, row.ItemArray.ElementAt(i).ToString(), getColumnName(i), Convert.ToUInt32(z)); }
                z++;
            }
        } 
        
    }
}

하지만 이 조각은 DataTable을 출력하기 위해 sloooooooooooooooooooowwww...

DataTable을 Excel로 빠르고 정확하게 내보내려면 어떻게 해야 합니까?

제가 짧은 예시를 썼습니다.저는 좋아요.테이블이 1개 있는 데이터 세트를 1개만 테스트했습니다만, 이 정도면 충분할 것 같습니다.

모든 셀을 String(SharedStrings도 아님)으로 취급하고 있는 것을 고려해 주세요.SharedStrings를 사용하는 경우 샘플을 약간 수정해야 할 수 있습니다.

편집: 이 작업을 수행하려면 WindowsBase 및 DocumentFormat을 추가해야 합니다.프로젝트에 대한 OpenXml 참조.

즐거운 시간 되세요.

private void ExportDataSet(DataSet ds, string destination)
        {
            using (var workbook = SpreadsheetDocument.Create(destination, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
            {
                var workbookPart = workbook.AddWorkbookPart();

                workbook.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook();

                workbook.WorkbookPart.Workbook.Sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets();

                foreach (System.Data.DataTable table in ds.Tables) {

                    var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>();
                    var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData();
                    sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData);

                    DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>();
                    string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);

                    uint sheetId = 1;
                    if (sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Count() > 0)
                    {
                        sheetId =
                            sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1;
                    }

                    DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet() { Id = relationshipId, SheetId = sheetId, Name = table.TableName };
                    sheets.Append(sheet);

                    DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row();

                    List<String> columns = new List<string>();
                    foreach (System.Data.DataColumn column in table.Columns) {
                        columns.Add(column.ColumnName);

                        DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
                        cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
                        cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName);
                        headerRow.AppendChild(cell);
                    }


                    sheetData.AppendChild(headerRow);

                    foreach (System.Data.DataRow dsrow in table.Rows)
                    {
                        DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
                        foreach (String col in columns)
                        {
                            DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
                            cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
                            cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); //
                            newRow.AppendChild(cell);
                        }

                        sheetData.AppendChild(newRow);
                    }

                }
            }
        }

eburgos, 데이터 세트에 여러 개의 데이터 파일이 있을 때 스프레드시트에 덮어쓰기되어 워크북에 한 장만 남아 있었기 때문에 코드를 약간 수정했습니다.기본적으로 워크북이 생성되는 부분을 루프 밖으로 이동했습니다.업데이트된 코드입니다.

private void ExportDSToExcel(DataSet ds, string destination)
{
    using (var workbook = SpreadsheetDocument.Create(destination, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
    {
        var workbookPart = workbook.AddWorkbookPart();
        workbook.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook();
        workbook.WorkbookPart.Workbook.Sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets();

        uint sheetId = 1;

        foreach (DataTable table in ds.Tables)
        {
            var sheetPart = workbook.WorkbookPart.AddNewPart<WorksheetPart>();
            var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData();
            sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData);                

            DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>();
            string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);

            if (sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Count() > 0)
            {
                sheetId =
                    sheets.Elements<DocumentFormat.OpenXml.Spreadsheet.Sheet>().Select(s => s.SheetId.Value).Max() + 1;
            }

            DocumentFormat.OpenXml.Spreadsheet.Sheet sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet() { Id = relationshipId, SheetId = sheetId, Name = table.TableName };
            sheets.Append(sheet);

            DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row();

            List<String> columns = new List<string>();
            foreach (DataColumn column in table.Columns)
            {
                columns.Add(column.ColumnName);

                DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
                cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
                cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName);
                headerRow.AppendChild(cell);
            }

            sheetData.AppendChild(headerRow);

            foreach (DataRow dsrow in table.Rows)
            {
                DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row();
                foreach (String col in columns)
                {
                    DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
                    cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
                    cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); //
                    newRow.AppendChild(cell);
                }

                sheetData.AppendChild(newRow);
            }
        }
    }
}

C#/VB도 썼어요.OpenXML을 사용하고 OpenXmlWriter도 사용하는 Net "Export to Excel" 라이브러리는 대용량 파일을 쓸 때 메모리가 부족하지 않습니다.

전체 소스 코드 및 데모는 여기에서 다운로드할 수 있습니다.

Excel로 내보내기

그것은 아주 사용하기 쉽다.쓰고 싶은 파일명을 전달해 주세요.DataTable,DataSet또는List<>.

CreateExcelFile.CreateExcelDocument(myDataSet, "MyFilename.xlsx");

ASP에서 호출하는 경우.넷 어플리케이션, 전달:HttpResponse파일을 쓸 수 있습니다.

CreateExcelFile.CreateExcelDocument(myDataSet, "MyFilename.xlsx", Response);

제 욕구를 충족시키는 것이 없어서 엑셀 라이터에게 직접 수출서를 작성했습니다.이 기능은 빠르고 셀의 상당한 포맷을 가능하게 합니다.다음 사이트에서 확인하실 수 있습니다.

https://openxmlexporttoexcel.codeplex.com/

도움이 됐으면 좋겠어요.

이 도서관을 한 번 둘러보세요.프로젝트 중 하나에 사용해 본 결과, 매우 사용하기 쉽고, 신뢰성이 높고, 고속입니다(데이터 내보내기용으로만 사용).

http://epplus.codeplex.com/

도서관은 여기서 보실 수 있습니다.문서 섹션에서 데이터 테이블을 가져오는 방법을 찾을 수 있습니다.

그냥 쓰기만 하면 돼

using (var doc = new SpreadsheetDocument(@"C:\OpenXmlPackaging.xlsx")) {
    Worksheet sheet1 = doc.Worksheets.Add("My Sheet");
    sheet1.ImportDataTable(ds.Tables[0], "A1", true);
}

도움이 됐으면 좋겠다!

수락한 답변을 시도해보니 생성된 엑셀 파일이 손상되었다는 메시지가 떴습니다.코드 말미에 추가하는 등 몇 가지 수정 작업을 통해 수정할 수 있었습니다.

workbookPart.Workbook.Save();

c#의 Open XML을 사용하여 Excel로 데이터 테이블을 내보냅니다.

OpenXML을 사용하여 데이터 테이블에서 Excel로 내보내기 위한 기준으로 이 질문의 주요 답변을 사용했지만 위의 방법보다 훨씬 빠르다는 것을 알고 OpenXMLWriter로 전환했기 때문에 이 답변을 추가하고 싶었습니다.

자세한 내용은 아래 링크에서 확인하실 수 있습니다.내 코드는 VB야NET 단, 변환해야 합니다.

DataTable을 Excel로 내보내는 방법

언급URL : https://stackoverflow.com/questions/11811143/export-datatable-to-excel-with-open-xml-sdk-in-c-sharp

반응형