@manhng

Welcome to my blog!

DocumentFormat.OpenXml and Excel Export

December 7, 2018 12:37

DocumentFormat.OpenXml and Excel Export (edit)

Vấn đề xuất Excel mà cần phải chỉnh lại format cho dữ liệu kiểu số, kiểu ngày (date), kiểu giờ (time) và kiểu ngày + giờ (datetime), sẽ được giải quyết qua đoạn code dưới

SQL Server

SELECT CONVERT(VARCHAR(10), CreatedTimeStamp, 101) + ' ' 
       + LTRIM(RIGHT(CONVERT(CHAR(20), CreatedTimeStamp, 22), 11)) as [CreatedTimeStamp_MMddyyyy_12H_AMPM]
,CONVERT(VARCHAR(10), ModifiedTimeStamp, 101) + ' ' 
       + LTRIM(RIGHT(CONVERT(CHAR(20), ModifiedTimeStamp, 22), 11)) as [ModifiedTimeStamp_MMddyyyy_12H_AMPM]
,CONVERT(VARCHAR(10), CreatedTimeStamp, 103) + ' ' 
       + LTRIM(RIGHT(CONVERT(CHAR(20), CreatedTimeStamp, 22), 11)) as [CreatedTimeStamp_ddMMyyyy_12H_AMPM]
,CONVERT(VARCHAR(10), ModifiedTimeStamp, 103) + ' ' 
       + LTRIM(RIGHT(CONVERT(CHAR(20), ModifiedTimeStamp, 22), 11)) as [ModifiedTimeStamp_ddMMyyyy_12H_AMPM]
From [dbo].[User]

declare @dt DateTime = GETDATE()
select  CONVERT(VARCHAR(10), @dt, 101) --12/07/2018
select  CONVERT(VARCHAR(10), @dt, 103) --07/12/2018
select  CONVERT(VARCHAR(10), @dt, 105) --07-12-2018
select  CONVERT(VARCHAR(10), @dt, 110) --12-07-2018

Custom Format Cells - Excel Example

Custom Date Format

Kiểu ngày trong Excel: dd/mm/yyyy

Kiểu giờ trong Excel: hh:mm:ss AM/PM

Kiểu ngày + giờ trong Excel: dd/mm/yyyy hh:mm:ss AM/PM

1) Lấy dữ liệu từ cơ sở dữ liệu lên

    private DataTable GetDataTableFromDatabase()
    {
        string constring = @"Data Source=.;Initial Catalog=Northwind;uid=sa;pwd=123456";
        using (SqlConnection con = new SqlConnection(constring))
        {
            using (SqlCommand cmd = new SqlCommand("SELECT * FROM [dbo].[User]", con))
            {
                cmd.CommandType = CommandType.Text;
                using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
                {
                    using (DataTable dt = new DataTable())
                    {
                        sda.Fill(dt);
                        return dt;
                    }
                }
            }
        }
    }

    private DataTable GetDataTableFromDatabase2()
    {
        string sqlConnectionString = @"Data Source=.;Initial Catalog=Northwind;uid=sa;pwd=123456";
        using (SqlConnection sqlConnection = new SqlConnection(sqlConnectionString))
        {
            sqlConnection.Open();
            using (SqlDataAdapter sqlDataAdapter = new SqlDataAdapter("SELECT * FROM [dbo].[User]", sqlConnection))
            {
                DataTable dataTable = new DataTable();
                sqlDataAdapter.Fill(dataTable);
                return dataTable;
            }
        }
    }

Sự kiện Page_Load

    protected void Page_Load(object sender, EventArgs e)
    {
        DataSet ds = new DataSet();
        ds.Tables.Add(GetDataTableFromDatabase());
        string m_DateFormat = "MM/dd/yyyy";
        string m_TimeFormat = "hh:mm:ss AM/PM"; //TODO: MANH
        GenerateExcel(ds, m_DateFormat, m_TimeFormat);
    }

OpenXml và định dạng dữ liệu

    public void GenerateExcel(DataSet data, string m_DateFormat, string m_TimeFormat)
    {
        var memoryStream = new MemoryStream();

        using (var workbook = SpreadsheetDocument.Create(memoryStream, 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();
            WorkbookStylesPart wbsp = workbookPart.AddNewPart();
            wbsp.Stylesheet = CreateStylesheet1(m_DateFormat, m_TimeFormat);
            wbsp.Stylesheet.Save();

            uint sheetId = 0;

            foreach (System.Data.DataTable table in data.Tables)
            {
                var sheetPart = workbook.WorkbookPart.AddNewPart();
                var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData();
                sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData);
                DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = workbook.WorkbookPart.Workbook.GetFirstChild();
                string relationshipId = workbook.WorkbookPart.GetIdOfPart(sheetPart);
                int k = sheets.ChildElements.Count;
                string bsd = sheets.InnerText;
                string jknkj = sheets.InnerXml;
                sheetId++; //TODO: MANH
                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 columns = new List();
                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)
                    {
                        DateTime dDate;
                        if (DateTime.TryParse(dsrow[col].ToString(), out dDate))
                        {
                            DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
                            cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.Number;
                            cell.StyleIndex = 1;//TODO: MANH
                            cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dDate.ToOADate().ToString());
                            newRow.AppendChild(cell);
                        }
                        else
                        {
                            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);
                }
            }
            workbookPart.Workbook.Save();
            workbook.Close();
        }

        string fileName = @"D:\\Excel_Samples\File_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss") + ".xlsx";
        Directory.CreateDirectory(Path.GetDirectoryName(fileName));
        using (FileStream file = new FileStream(fileName, FileMode.Create))
        {
            memoryStream.WriteTo(file);
            file.Close();
            memoryStream.Close();
        }
    }

    private Stylesheet CreateStylesheet1(string m_DateFormat, string m_TimeFormat)
    {
        Stylesheet ss = new Stylesheet();

        Fonts fts = new Fonts();
        DocumentFormat.OpenXml.Spreadsheet.Font ft = new DocumentFormat.OpenXml.Spreadsheet.Font();
        FontName ftn = new FontName();
        ftn.Val = "Calibri";
        DocumentFormat.OpenXml.Spreadsheet.FontSize ftsz = new DocumentFormat.OpenXml.Spreadsheet.FontSize();
        ftsz.Val = 11;
        ft.FontName = ftn;
        ft.FontSize = ftsz;
        fts.Append(ft);
        fts.Count = (uint)fts.ChildElements.Count;

        Fills fills = new Fills();
        Fill fill;
        PatternFill patternFill;
        fill = new Fill();
        patternFill = new PatternFill();
        patternFill.PatternType = PatternValues.None;
        fill.PatternFill = patternFill;
        fills.Append(fill);
        fill = new Fill();
        patternFill = new PatternFill();
        patternFill.PatternType = PatternValues.Gray125;
        fill.PatternFill = patternFill;
        fills.Append(fill);
        fills.Count = (uint)fills.ChildElements.Count;

        Borders borders = new Borders();
        Border border = new Border();
        border.LeftBorder = new LeftBorder();
        border.RightBorder = new RightBorder();
        border.TopBorder = new TopBorder();
        border.BottomBorder = new BottomBorder();
        border.DiagonalBorder = new DiagonalBorder();
        borders.Append(border);
        borders.Count = (uint)borders.ChildElements.Count;

        CellStyleFormats csfs = new CellStyleFormats();
        CellFormat cf = new CellFormat();
        cf.NumberFormatId = 0;
        cf.FontId = 0;
        cf.FillId = 0;
        cf.BorderId = 0;
        csfs.Append(cf);
        csfs.Count = (uint)csfs.ChildElements.Count;

        uint iExcelIndex = 1;//TODO: MANH
        NumberingFormats nfs = new NumberingFormats();
        CellFormats cfs = new CellFormats();

        cf = new CellFormat();
        cf.NumberFormatId = 0;
        cf.FontId = 0;
        cf.FillId = 0;
        cf.BorderId = 0;
        cf.FormatId = 0;
        cfs.Append(cf);

        NumberingFormat nf;
        nf = new NumberingFormat();
        nf.NumberFormatId = iExcelIndex++;
        string formatCodeDateTime = string.Format("{0} {1}", m_DateFormat, m_TimeFormat);//TODO: MANH
        nf.FormatCode = StringValue.FromString(formatCodeDateTime);//TODO: MANH
        //nf.FormatCode = StringValue.FromString("mm-d-yy h:mm:ss AM/PM");//TODO: MANH
        nfs.Append(nf);
        cf = new CellFormat();
        cf.ApplyNumberFormat = true;
        cf.NumberFormatId = nf.NumberFormatId;
        cf.FontId = 0;
        cf.FillId = 0;
        cf.BorderId = 0;
        cf.FormatId = 0;
        cfs.Append(cf);

        nf = new NumberingFormat();
        nf.NumberFormatId = iExcelIndex++;
        nf.FormatCode = "#,##0.0000";
        nfs.Append(nf);
        cf = new CellFormat();
        cf.NumberFormatId = nf.NumberFormatId;
        cf.FontId = 0;
        cf.FillId = 0;
        cf.BorderId = 0;
        cf.FormatId = 0;
        cf.ApplyNumberFormat = true;
        cfs.Append(cf);

        // #,##0.00 is also Excel style index 4
        nf = new NumberingFormat();
        nf.NumberFormatId = iExcelIndex++;
        nf.FormatCode = "#,##0.00";
        nfs.Append(nf);
        cf = new CellFormat();
        cf.NumberFormatId = nf.NumberFormatId;
        cf.FontId = 0;
        cf.FillId = 0;
        cf.BorderId = 0;
        cf.FormatId = 0;
        cf.ApplyNumberFormat = true;
        cfs.Append(cf);

        // @ is also Excel style index 49
        nf = new NumberingFormat();
        nf.NumberFormatId = iExcelIndex++;
        nf.FormatCode = "@";
        nfs.Append(nf);
        cf = new CellFormat();
        cf.NumberFormatId = nf.NumberFormatId;
        cf.FontId = 0;
        cf.FillId = 0;
        cf.BorderId = 0;
        cf.FormatId = 0;
        cf.ApplyNumberFormat = true;
        cfs.Append(cf);

        nfs.Count = (uint)nfs.ChildElements.Count;
        cfs.Count = (uint)cfs.ChildElements.Count;

        ss.Append(nfs);
        ss.Append(fts);
        ss.Append(fills);
        ss.Append(borders);
        ss.Append(csfs);
        ss.Append(cfs);

        CellStyles css = new CellStyles();
        CellStyle cs = new CellStyle();
        cs.Name = "Normal";
        cs.FormatId = 0;
        cs.BuiltinId = 0;
        css.Append(cs);
        css.Count = (uint)css.ChildElements.Count;
        ss.Append(css);

        DifferentialFormats dfs = new DifferentialFormats();
        dfs.Count = 0;
        ss.Append(dfs);

        TableStyles tss = new TableStyles();
        tss.Count = 0;
        tss.DefaultTableStyle = "TableStyleMedium9";
        tss.DefaultPivotStyle = "PivotStyleLight16";
        ss.Append(tss);

        return ss;
    }

Happy Coding!

Work with EXCEL using NPOI and EPPlus

May 11, 2018 22:38

Work with EXCEL using NPOI and EPPlus
https://www.codeproject.com/Articles/1241654/Export-to-Excel-using-NPOI-Csharp-and-WEB-API
http://www.zachhunter.com/2015/11/xlsx-template-with-epplus-and-web-api-save-as-xlsx-or-pdf/
https://www.codeproject.com/Articles/1194712/Advanced-Excels-With-EPPlus

Làm việc với Excel trong .NET

March 24, 2018 20:43

Làm việc với Excel trong .NET

1) Sử dụng thư viện EPPlus

1.1) Thao tác cơ bản khi làm việc với Excel sử dụng thư viện EPPlus

https://www.codeproject.com/Tips/1118204/EPPlus-Basics-and-Snippets-Cheatsheet-for-generati

27 Aug 2016

1.2) Simple POCO Mapper for EPPlus

https://www.codeproject.com/Articles/1202924/Simple-POCO-Mapper-for-EPPlus

27 Aug 2017

Mapping theo cột hoặc theo hàng để đọc tệp Excel theo chiều ngang và chiều dọc:

Merge cells

http://w3cgeek.com/epplus-how-to-style-merged-cells.html

c# - Merge cells using EPPlus? - Stack Overflow

ws.Cells["A1:C1"].Merge = true;

2) Sử dụng thư viện Bytescout.SpreadSheet

https://www.c-sharpcorner.com/UploadFile/17e8f6/reading-merged-cell-from-excel-using-bytescout-spreadsheet-i/

Đọc tệp Excel khi đã merge rows hoặc merge cells

Các thư viện làm việc với Excel

March 14, 2018 21:18

SpreadsheetLight (edit)

SpreadsheetLight is an open source Open XML spreadsheet library for .NET Framework written in C#, and is released under the MIT License. You can create new Open XML spreadsheets, or work with existing Open XML spreadsheets that are compatible with Microsoft Excel 2007/2010/2013 and LibreOffice Calc.

No Office/Excel Interop needed. You do not need Microsoft Office/Excel to be installed.

Dependency: Open XML SDK 2.5 

Search Google:

https://stackoverflow.com/questions/9401508/repaired-records-cell-information-from-worksheet-created-from-scratch
https://stackoverflow.com/questions/11706393/excel-found-unreadable-content-in-xlsx

https://www.aspsnippets.com/Articles/OpenXml-MVC-Example-Export-to-Excel-using-OpenXml-in-ASPNet-MVC.aspx
https://sanushabalan.wordpress.com/2018/01/05/read-excel-file-using-open-xml-in-asp-net-c/
https://www.codeproject.com/articles/667514/using-asp-net-mvc-and-openxml-api-to-stream-excel
https://gist.github.com/skpaul/7e02ce3e92e9f9917744

DocumentFormat.OpenXml

The Open XML SDK provides tools for working with Office Word, Excel, and PowerPoint documents.

This is the 4th part of OpenXML Spreadsheet Tutorial Series:

http://www.dispatchertimer.com/tutorial/how-to-create-an-excel-file-in-net-using-openxml-part-1-basics/

http://www.dispatchertimer.com/tutorial/how-to-create-an-excel-file-in-net-using-openxml-part-2-export-a-collection-to-spreadsheet/

http://www.dispatchertimer.com/tutorial/how-to-create-an-excel-file-in-net-using-openxml-part-3-add-stylesheet-to-the-spreadsheet/

http://www.dispatchertimer.com/tutorial/how-to-create-an-excel-file-in-net-using-openxml-part-4-draw-chart/

http://www.dispatchertimer.com/troubleshooting/troubleshooting-openxml-spreadsheet/

Autofit column

https://stackoverflow.com/questions/31197038/how-to-autofit-excel-column-using-openxml-package

Number Format:

https://stackoverflow.com/questions/7872116/applying-number-format-to-a-cell-value-using-openxml

ClosedXML

 

ExcelPackage

 

OpenXmlPowerTools

The Open XML PowerTools provides guidance and example code for programming with Open XML Documents (DOCX, XLSX, and PPTX). It is based on, and extends the functionality of the Open XML SDK.

ExtremeML

ExtremeML adds new power to the OpenXML SDK 2.0, enabling packages to be created and edited via an intuitive object model and freeing developers from the burden of implementing the low-level detail of OpenXML.

Tim Coulter viết ra thư viện ExtremeML, một thư viện Opensource tuyệt vời để làm việc với Excel 2007.

ExtremeML được mô tả như sau:


Sau đây là các tính năng chính của ExtremeML:

  • Tạo mới hoặc mở 1 workbook.
  • Đọc và ghi dữ liệu từ stream.
  • Thêm, xóa, thay đổi các worksheet.
  • Thêm, xóa, sửa row và column.
  • Hỗ trợ strongly-typed.
  • Đọc và ghi các formula của cells.
  • Đọc, ghí và thay đổi dữ liệu ảnh, rich text.
  • Hỗ trợ footer và header.

Ngoài ra ExtremeML còn hỗ trợ các tính năng sau:

  • Hỗ trợ dữ liệu dựa trên dạng bảng của Excel table.
  • Hỗ trợ template.
  • Các tính năng nâng cao như: group, merge, macro và phiên bản mới nhất hỗ trợ Excel 2010.

Ví dụ đoạn code sau:

public static void PopulateDataTypesRandom()
{

    using (var package = SpreadsheetDocumentWrapper.Open("MyWorkbook.xlsx"))
    {
        var table = package.WorkbookPart.GetTablePart("DataTypes").Table;
        var data = new List<object[]>();
        for (var i = 0; i < 10; i++)
        {
            data.Add(new
            object[]
            {
                Utility.GetRandomString(),
                Utility.GetRandomUri(),
                Utility.GetRandomDateTime(),
                Utility.GetRandomTimeSpan(),
                Utility.GetRandomInteger(),
                Utility.GetRandomDouble(),
                Utility.GetRandomDecimal(),
                Utility.GetRandomBoolean()
            }
            );
        }
        table.Fill(data.ToArray());
    }
}

Một số class hữu ích sưu tầm

https://gist.github.com/hadoan/

Phím tắt Excel

July 1, 2017 12:40

https://www.facebook.com/permalink.php?story_fbid=1304749679660585&id=100003766955259

Split text into different columns with the Convert Text to Columns Wizard

May 11, 2017 15:43

You can take the text in one or more cells, and spread it out across multiple cells. This is called parsing, and is the opposite of concatenating, where you can combine text from two or more cells into one cell. For example, if you have a column of full names, you can split that column into separate first name and last name columns, like this:

Before and after of text split into different columns

Go to Data > Text to Columns, and the wizard will walk you through the process. Here’s a full breakdown of how it works:

  1. Select the cell or column that contains the text you want to split.

    NOTE:  Select as many rows as you want, but no more than one column. Make sure there’s enough empty columns to the right so nothing over there gets overwritten. If you don’t have enough empty columns, add them.

  2. Click Data >Text to Columns.

    Click the Data tab, and then click Text to Columns

  3. This starts the Convert Text to Columns Wizard. Click Delimited > Next.

  4. Check Space, and clear the rest of the boxes, or check Comma and Space if that is how your text is split (Smith, John, with a comma and space between the names). You can see a preview of your data in the Data preview window.

    Step 2 in the Convert Text to Columns Wizard

  5. Click Next.

  6. In this step, you pick the format for your new columns, or you can let Excel do it for you. If you want to pick your own format, select the format you want, such as Text, click the second column of data in the Data preview window, and click the same format again. Repeat for all the columns in the preview window.

    Step 3 in the Convert Text to Columns Wizard

  7. Click the Collapse Dialog Box button image button to the right of the Destination box to collapse the dialog box.

  8. Select the cells in your workbook where you want to paste your split data. For example, if you are dividing a full name into a first name column and a last name column, select the appropriate number of cells in two adjacent columns.

    Select the cells where you wnt to paste your split cells

  9. Click the Expand Dialog Box button image button to expand the dialog box, and then click Finish.

    Expand the dialog box when you're done selecting your cells.

Categories

Recent posts