Search code examples
c#asp.netexcelopenxml

Convert Excel Cell Value From Number To Text Using C#


I am using the below process to open my excel:

if (dt != null) 
{
    foreach(DataColumn dc in dt.Columns) 
    {
        Response.Write(dc.ColumnName + "\t");
        //sep = ";";
    }
    Response.Write(System.Environment.NewLine);
    foreach(DataRow dr in dt.Rows) 
    {
        for (int i = 0; i < dt.Columns.Count; i++) 
        {
            Response.Write(dr[i].ToString() + "\t");
        }
        Response.Write("\n");
    }

    Response.Flush();
    Response.SuppressContent = true;
    HttpContext.Current.ApplicationInstance.CompleteRequest();
}

In my datatable I have one numeric value which align to right when excel renders as this is the default property of excel to align numeric values right. But as per my requirement I have to align that numeric value to the left side in excel. For this I tried adding the space from the back-end but excel ignore space when renders. I tried adding ' before the column value but when excel renders the column value shows like '2015, '2016.

Anybody can help me to figure this out. Thanks in advance.


Solution

  • You're exporting as a CSV file. If you use OpenXML you will be able to specify Column DataTypes (formats) and also apply Left Alignment to numbers eg:

    using OfficeOpenXml;
    using OfficeOpenXml.Style;
    
    public static bool IsNumeric(this DataColumn col) {
        if (col == null)
            return false;
    
        //This should be moved to const in order to improve performance
        var numericTypes = new [] { typeof(Byte), typeof(Decimal), typeof(Double), typeof(Int16), typeof(Int32), typeof(Int64), typeof(SByte), typeof(Single), typeof(UInt16), typeof(UInt32), typeof(UInt64)};
        return numericTypes.Contains(col.DataType);
    }
    
    public static void ExportToExcelOpen(DataSet ds, string filename)
    {
        // Create a spreadsheet document by supplying the filename
        // By default, AutoSave = true, Editable = true, and Type = xlsx
    
        HttpContext.Current.Response.ClearHeaders();
        HttpContext.Current.Response.ClearContent();
        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.Buffer = true;
        HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=" + filename);
        HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        HttpContext.Current.Response.Charset = "";
    
        MemoryStream ms = new MemoryStream();
    
        using (var objSpreadsheet = SpreadsheetDocument.Create(ms, DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook))
        {
            var workbookPart = objSpreadsheet.AddWorkbookPart();
            objSpreadsheet.WorkbookPart.Workbook = new DocumentFormat.OpenXml.Spreadsheet.Workbook();
            objSpreadsheet.WorkbookPart.Workbook.Sheets = new DocumentFormat.OpenXml.Spreadsheet.Sheets();
    
            uint sheetId = 1;
    
            foreach (DataTable table in ds.Tables)
            {
                var sheetPart = objSpreadsheet.WorkbookPart.AddNewPart<WorksheetPart>();
                var sheetData = new DocumentFormat.OpenXml.Spreadsheet.SheetData();
                sheetPart.Worksheet = new DocumentFormat.OpenXml.Spreadsheet.Worksheet(sheetData);
    
                DocumentFormat.OpenXml.Spreadsheet.Sheets sheets = objSpreadsheet.WorkbookPart.Workbook.GetFirstChild<DocumentFormat.OpenXml.Spreadsheet.Sheets>();
                string relationshipId = objSpreadsheet.WorkbookPart.GetIdOfPart(sheetPart);
    
                sheetId += 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();
    
                Dictionary<string, bool> columns = new Dictionary<string, bool>(); 
                foreach (DataColumn column in table.Columns) 
                { 
                    //Check for numeric column HERE!!
                    columns.Add(column.ColumnName, column.IsNumeric());   
    
                    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);
    
                NumberFormatInfo valueNumberFormatInfo = new NumberFormatInfo() { NumberDecimalSeparator = ".", NumberGroupSeparator = String.Empty };
                foreach (DataRow dsrow in table.Rows) 
                { 
                    DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row(); 
                    foreach (KeyValuePair<string, bool> col in columns) 
                    { 
                        DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
                        if (col.Value)
                        {
                            cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.Number; 
                            cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(String.Format(valueNumberFormatInfo, "0.####################", dsrow[col.Key]));
                             //Left Alignment HERE
                             cell.Style.HorizontalAlignment = ExcelHorizontalAlignment.Left;
                        }
                        else
                        {
                            cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String; 
                            cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col.Key].ToString());
                        } 
                        newRow.AppendChild(cell); 
                    } 
    
                    sheetData.AppendChild(newRow); 
                }
            }
    
            objSpreadsheet.Close();
            ms.WriteTo(HttpContext.Current.Response.OutputStream);
            ms.Close();
    
            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.End();
        }
    }
    

    REF: http://forums.asp.net/t/1860267.aspx?How+to+retain+data+types+when+exporting+to+Excel+using+Open+XML

    REF: Set text align to center in an Excel document using OpenXML with C#