Formatting a column with EPPLUS Excel Library - c#

I wrote a C# program to create an excel spreadsheet. The sheet has multiple columns. I want to format ONE of the columns.
aFile = new FileInfo(excelDocName); // excelDocName is a string
ExcelPackage pck = new ExcelPackage(aFile);
var ws = pck.Workbook.Worksheets.Add("Content");
ws.View.ShowGridLines = true;
ws.Cells["B:B"].Style.Numberformat.Format = "0.00";
ws.Cells[1, 1].Value = "AA";
ws.Cells[1, 2].Value = "BB";
ws.Cells[1, 3].Value = "CC";
ws.Cells[1, 4].Value = "DD";
for (int row = 2; row <= 10; ++row)
for (int col = 1; col <= 4; ++col)
{
ws.Cells[row, col].Value = row * col;
}
ws.Row(1).Style.Font.Bold = true;
pck.Save();
The problem is, while it's formatting the column correct, it's also formatting other columns with the format and not just the column I specified.
I also tried:
ws.Column(1).Style.Numberformat.Format = "0.00";
Is this a bug or am I missing something?

Are you opening an existing file? It may have a format already applied to the other columns prior to you opening it. Or a template like astian said.
Clear all the formatting just in case like this:
ws.Cells["A:D"].Style.Numberformat.Format = null;
ws.Cells["B:B"].Style.Numberformat.Format = "0.00";
Full unit test in EPPlus 4.0.3:
[TestMethod]
public void Format_Single_Column_Test()
{
//http://stackoverflow.com/questions/28698226/formatting-a-column-with-epplus-excel-library
var excelDocName = #"c:\temp\temp.xlsx";
var aFile = new FileInfo(excelDocName); // excelDocName is a string
if (aFile.Exists)
aFile.Delete();
ExcelPackage pck = new ExcelPackage(aFile);
var ws = pck.Workbook.Worksheets.Add("Content");
ws.View.ShowGridLines = true;
ws.Cells["A:D"].Style.Numberformat.Format = null;
ws.Cells["B:B"].Style.Numberformat.Format = "0.00";
ws.Cells[1, 1].Value = "AA";
ws.Cells[1, 2].Value = "BB";
ws.Cells[1, 3].Value = "CC";
ws.Cells[1, 4].Value = "DD";
for (int row = 2; row <= 10; ++row)
for (int col = 1; col <= 4; ++col)
{
ws.Cells[row, col].Value = row*col;
}
ws.Row(1).Style.Font.Bold = true;
pck.Save();
}

Related

C# Index was out of range error when export to excel small amount of data

I have a winform built in C# which can export data from SQL and then allows exporting it to Excel. The problem I faced is when I have only one row of data table wont be exported and I get an error that index is out of range. There is no problem whatsoever if there are two rows and more. Could you help me figure out what should be fixed? Debugging brings me to line - saveFileDialog1.FileName = "Report - " + dataGridView1.Rows[1].Cells[0].Value.ToString();
private void btnExport1_Click(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
this.Text = "Exporting...";
_Application excel = new Microsoft.Office.Interop.Excel.Application();
_Workbook workbook = excel.Workbooks.Add(Type.Missing);
_Worksheet worksheet = null;
Range headersRow;
Range allData;
Range updateTimestamp;
saveFileDialog1.FileName = "Report - " + dataGridView1.Rows[1].Cells[0].Value.ToString();
excel.ActiveWindow.Zoom = 80;
try
{
worksheet = workbook.ActiveSheet;
worksheet.Name = "Summary";
worksheet.Cells.WrapText = false;
worksheet.Cells.Font.Name = "Text";
worksheet.Cells.Interior.Color = Color.FromArgb(255, 255, 255);
worksheet.Cells.NumberFormat = "#";
for (int rowIndex = 0; rowIndex < dataGridView1.Rows.Count ; rowIndex++)
{
for (int colIndex = 0; colIndex < dataGridView1.Columns.Count +1; colIndex++)
{
if (rowIndex == 0)
{
worksheet.Cells[rowIndex + 4, colIndex + 1] = dataGridView1.Columns[colIndex].HeaderText;
}
else
{
worksheet.Cells[rowIndex + 4, colIndex + 1] = dataGridView1.Rows[rowIndex-1].Cells[colIndex].Value.ToString();
}
}
}
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
worksheet.Columns.AutoFit();
// worksheet.Application.ActiveWindow.SplitRow = 4;
// worksheet.Application.ActiveWindow.FreezePanes = true;
worksheet.Shapes.AddPicture(#"... logo.png", Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoCTrue, 0, 0, 180, 39);
allData = worksheet.UsedRange;
allData.Borders.LineStyle = XlLineStyle.xlContinuous;
Microsoft.Office.Interop.Excel.Range ur = worksheet.UsedRange;
Microsoft.Office.Interop.Excel.Range r = worksheet.Cells[4, ur.Columns.Count];
headersRow = worksheet.Range["A4", r];
headersRow.Cells.Font.Bold = true;
headersRow.Cells.Font.Color = Color.FromArgb(255, 255, 255);
headersRow.Cells.Interior.Color = Color.FromArgb(0, 055, 085);
worksheet.Cells[2, 5] = worksheet.Cells[5, 19];
worksheet.Cells[2, 5].Font.Bold = true;
worksheet.Cells[2, 4] = "Report date:";
worksheet.Cells[2, 4].Font.Bold = true;
worksheet.Cells[2, 4].HorizontalAlignment = XlHAlign.xlHAlignRight;
updateTimestamp = worksheet.Range["S5", "S5"].EntireColumn;
updateTimestamp.Delete();

Formatting Excel Sheet using C#. The Style apply to all cells not to one cell

I'm using a extension method to export DataTable to Excel. When I format cell style, Alignment and Font Size it applies to all cells in the sheet.
Here is my code
public static void ExportToExcel(this System.Data.DataTable DataTable, string ExcelFilePath = null, string address = "", string reportName = "")
{
try
{
int ColumnsCount;
if (DataTable == null || (ColumnsCount = DataTable.Columns.Count) == 0)
throw new Exception("ExportToExcel: Null or empty input table!\n");
// load excel, and create a new workbook
Microsoft.Office.Interop.Excel.Application Excel = new Microsoft.Office.Interop.Excel.Application();
Excel.Workbooks.Add();
// single worksheet
Microsoft.Office.Interop.Excel._Worksheet Worksheet = Excel.ActiveSheet;
object[] Header = new object[ColumnsCount];
// column headings
for (int i = 0; i < ColumnsCount; i++)
Header[i] = DataTable.Columns[i].ColumnName;
Microsoft.Office.Interop.Excel.Range HeaderRange = Worksheet.get_Range((Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[10, 1]), (Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[10, ColumnsCount]));
HeaderRange.Value = Header;
HeaderRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Gold);
HeaderRange.Font.Bold = true;
// DataCells
int RowsCount = DataTable.Rows.Count;
object[,] Cells = new object[RowsCount, ColumnsCount];
for (int j = 0; j < RowsCount; j++)
for (int i = 0; i < ColumnsCount; i++)
Cells[j, i] = DataTable.Rows[j][i];
//Custom Header
Worksheet.Range[Worksheet.Cells[1, 1], Worksheet.Cells[1, ColumnsCount]].Merge();
Worksheet.Range[Worksheet.Cells[1, 1], Worksheet.Cells[2, ColumnsCount]].Merge();
Worksheet.Cells[1, 1].Value = "DISTRIBUTOR SYSTEM";
Worksheet.Cells[1, 1].Style.Font.Size = 18;
Worksheet.Cells[1, 1].Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Aqua);
Worksheet.Cells[1].Style.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
Worksheet.Cells[1].Style.VerticalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
Worksheet.Range[Worksheet.Cells[3, 1], Worksheet.Cells[3, 2]].Merge();
Worksheet.Cells[3, 1].Value = "Invoice Date";
Worksheet.Cells[3, 1].Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Aqua);
Worksheet.Range[Worksheet.Cells[3, 3], Worksheet.Cells[3, 4]].Merge();
Worksheet.Cells[3, 3].Value = System.DateTime.Today.ToShortDateString();
Worksheet.Cells[3, 3].Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Aqua);
Worksheet.Range[Worksheet.Cells[4, 1], Worksheet.Cells[4, ColumnsCount]].Merge();
Worksheet.Cells[4, 1].Value = reportName;
Worksheet.Cells[4, 1].Style.Font.Size = 18;
Worksheet.Range[Worksheet.Cells[6, 1], Worksheet.Cells[6, ColumnsCount]].Merge();
Worksheet.Cells[6, 1].Value = address;
//Worksheet.Range[Worksheet.Cells[1, 1], Worksheet.Cells[1, 7]].Style.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
//Worksheet.Range[Worksheet.Cells[1, 1], Worksheet.Cells[1, 7]].Style.VerticalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignCenter;
//Worksheet.Range[Worksheet.Cells[11, 7], Worksheet.Cells[RowsCount + 1, 7]].Style.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignRight;
Worksheet.get_Range((Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[11, 1]), (Microsoft.Office.Interop.Excel.Range)(Worksheet.Cells[RowsCount + 1, ColumnsCount])).Value = Cells;
Worksheet.Range[Worksheet.Cells[10, 4], Worksheet.Cells[RowsCount + 1, 4]].EntireColumn.NumberFormat = "yyyy/MM/dd hh:mm";
Worksheet.Range[Worksheet.Cells[10, 11], Worksheet.Cells[RowsCount + 1, 7]].EntireColumn.NumberFormat = "####0.00";
Worksheet.Cells[RowsCount + 2, 1].Value = "TOTAL";
Worksheet.Cells[RowsCount + 2, 1].Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Gold);
Worksheet.Cells[RowsCount + 2, 7].Formula = "=Sum(" + Worksheet.Cells[11, 7].Address + ":" + Worksheet.Cells[RowsCount + 1, 7].Address + ")";
Worksheet.Columns[7].ColumnWidth = 18.00;
Worksheet.Columns[6].ColumnWidth = 18.00;
Worksheet.Columns[5].ColumnWidth = 18.00;
// check fielpath
if (ExcelFilePath != null && ExcelFilePath != "")
{
try
{
Worksheet.SaveAs(ExcelFilePath);
Excel.Quit();
MessageBox.Show("Excel file saved!");
}
catch (Exception ex)
{
throw new Exception("ExportToExcel: Excel file could not be saved! Check filepath.\n"
+ ex.Message);
}
}
else // no filepath is given
{
Excel.Visible = true;
}
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
throw new Exception("ExportToExcel: \n" + ex.Message);
}
}
I only need to set font size and alignment center horizontally and vertically in cell 1, cell 4 and cell 6
Help plz
Using .Style in Excel Interop seems to change the style in the whole sheet, as highlighted here: Changing font size of one cell in excel using C#
Try applying font and alignment changes directly to cells/ranges w/o accessing their style.
to set font size and alignment center horizontally and vertically in cell 1, cell 4 and cell 6 ... try
{
Worksheet.Cells[1, i].Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
Worksheet.Cells[1, i].Style.VerticalAlignment = OfficeOpenXml.Style.ExcelVerticalAlignment.Center;
Worksheet.Cells[1, i].Style.Font.Size = 20;
}

Check each value in the 3rd column of excel and if less than 4, change the row color? C#

I'm creating an Excel sheet and filling it with values using c#.
Before I save it, I want to check the 3rd column of the excel sheet and check if each value is less than 4. If it is I want to change that row to red.
Here is what I've tried so far:
Microsoft.Office.Interop.Excel.Application excel;
Microsoft.Office.Interop.Excel.Workbook worKbooK;
Microsoft.Office.Interop.Excel.Worksheet worKsheeT;
Microsoft.Office.Interop.Excel.Range celLrangE;
int totalcount = 0;
excel = new Microsoft.Office.Interop.Excel.Application();
excel.Visible = false;
excel.DisplayAlerts = false;
worKbooK = excel.Workbooks.Add(Type.Missing);
worKsheeT = (Microsoft.Office.Interop.Excel.Worksheet)worKbooK.ActiveSheet; worKsheeT.Name = "Model Results";
worKsheeT.Cells[1, 1] = "Name";
worKsheeT.Cells[1, 2] = "Id";
worKsheeT.Cells[1, 3] = "Sales";
for (int totalcount= 3; totalcount< dataGridView2.Columns.Count; )
{
GetSalesNumbers();
worKsheeT.Cells[totalcount, 1] = Name;
worKsheeT.Cells[totalcount, 2] = Id;
worKsheeT.Cells[totalcount, 3] = SalesNumber;
totalcount ++;
}
celLrangE = worKsheeT.Range[worKsheeT.Cells[1, 1], worKsheeT.Cells[totalcount + 5, 15]];
celLrangE.EntireColumn.AutoFit();
Excel.Range usedRange = worKsheeT.UsedRange;
Excel.Range rows = usedRange.Rows;
int count = 0;
foreach (Excel.Range row in rows)
{
if (count > 0)
{
Excel.Range firstCell = row.Cells[count,3];
string firstCellValue = firstCell.Value as String;
if (Convert.ToDouble(firstCellValue)<4)
{
row.Interior.Color = System.Drawing.Color.Red;
}
}
count++;
}
But this doesn't work, it keeps getting the cell value as Null
This is what I ended up using, I gave up on the other code
celLrangE = worKsheeT.Range[worKsheeT.Cells[1, 1],worKsheeT.Cells[totalcount + 5, 15]];
celLrangE.EntireColumn.AutoFit();
for (int row = 3; row <= totalcount; row++)
{
if (Convert.ToDouble(worKsheeT.Cells[row, 3].Value) < 4)
{
Excel.Range rows = worKsheeT.Range[worKsheeT.Cells[row,1],worKsheeT.Cells[row,15]];
rows.Interior.Color = System.Drawing.Color.Red;
}
}

How can i export the Dates?

Microsoft.Office.Interop.Excel.Application Excel = new Microsoft.Office.Interop.Excel.Application();
Workbook wb = Excel.Workbooks.Add(XlSheetType.xlWorksheet);
Worksheet ws = (Worksheet)Excel.ActiveSheet;
Excel.Visible = true;
ws.Cells[1, 1] = "Tarih";
ws.Cells[1, 2] = "Kasiyer";
ws.Cells[1, 3] = "Ucret";
ws.Cells[1, 4] = "Bilet No";
ws.Cells[1, 5] = "Firma Adı";
for (int j = 2; j < dataGridView1.Rows.Count; j++)
{
for (int i = 2; i <= 5; i++)
{
ws.Cells[j,i]=dataGridView1.Rows[j-2].Cells[i-1].Value;
}
}
Dates are not coming to First Cell in Excel . How can i do that ? please help me ? And also i have got a warning like "HRESULT özel durum döndürdü: 0x800AC472"
You can't probably take date value, it returns null and gives an error. Just for date column, you try to convert.
for (int i = 1; i < dataGridView1.Rows.Count; i++)
{
ws.Cells[i,0] = (Convert.ToDateTime(ws.Cells[i,0]).ToOADate();
}
Additionaly you can try that too.
Microsoft.Office.Interop.Excel.Range range = (Microsoft.Office.Interop.Excel.Range)xlWorkSheet.Cells[1, 1];
range = range.get_Resize(rowCount, columnCount);
range.EntireColumn.NumberFormat = "DD/MM/YYYY";

How to export data table with proper formatting and write text in Excel using C# Microsoft.Office.Interop.Excel?

I'm using this function to export a data table into excel.
protected void ExportExcel(System.Data.DataTable dt)
{
if (dt == null||dt.Rows.Count==0) return;
Microsoft.Office.Interop.Excel.Application xlApp =
new Microsoft.Office.Interop.Excel.Application();
if (xlApp == null)
{
return;
}
System.Globalization.CultureInfo CurrentCI =
System.Threading.Thread.CurrentThread.CurrentCulture;
System.Threading.Thread.CurrentThread.CurrentCulture =
new System.Globalization.CultureInfo("en-US");
Microsoft.Office.Interop.Excel.Workbooks workbooks = xlApp.Workbooks;
Microsoft.Office.Interop.Excel.Workbook workbook =
workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet);
Microsoft.Office.Interop.Excel.Worksheet worksheet =
(Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[1];
Microsoft.Office.Interop.Excel.Range range;
long totalCount = dt.Rows.Count;
long rowRead = 0;
float percent = 0;
for (int i = 0; i < dt.Columns.Count; i++)
{
worksheet.Cells[1, i + 1] = dt.Columns[i].ColumnName;
range = (Microsoft.Office.Interop.Excel.Range)worksheet.Cells[1, i + 1];
range.Interior.ColorIndex = 15;
range.Font.Bold = true;
}
for (int r = 0; r < dt.Rows.Count; r++)
{
for (int i = 0; i < dt.Columns.Count; i++)
{
worksheet.Cells[r + 2, i + 1] = dt.Rows[r][i].ToString();
}
rowRead++;
percent = ((float)(100 * rowRead)) / totalCount;
}
xlApp.Visible = true;
}
As you can see in the resulting excel image, the columns are not properly formatted i.e., the column sizes do not adapt to the databound items. How will I make the excel cells auto-adjust according to the data table?
And I also would like to add some text, maybe a header, for say maybe "System.DateTime.Now" or "data table name". How do i do this?
You should be able to format the columns like so:
Microsoft.Office.Interop.Excel.Range columns = worksheet.UsedRange.Columns;
columns.AutoFit();
You can insert a new row and place the current date as the title like so:
worksheet.Rows[1].Insert();
Excel.Range newRow = worksheet.Rows[1];
Excel.Range newCell = newRow.Cells[1];
newCell.Value = DateTime.Now.ToString("yyyy-MM-dd");
Also add this to your using statements so you don't need to use the fully qualified name every time you use an Excel object:
using Excel = Microsoft.Office.Interop.Excel;
Also, I have tidied up your method, by adding a few using statements to reduce clutter, removing some unnecessary casting and an unnesscessary check for null on the application object, just after it had been assigned:
using Excel = Microsoft.Office.Interop.Excel;
using System.Globalization;
using System.Threading;
using System.Data;
protected void ExportExcel(DataTable dt)
{
if (dt == null || dt.Rows.Count == 0) return;
var xlApp = new Excel.Application();
//Is this used?
CultureInfo CurrentCI = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Excel.Workbooks workbooks = xlApp.Workbooks;
Excel.Range range
Excel.Workbook workbook = workbooks.Add();
Excel.Worksheet worksheet = workbook.Worksheets[1];
long totalCount = dt.Rows.Count;
long rowRead = 0;
float percent = 0;
for (var i = 0; i < dt.Columns.Count; i++)
{
worksheet.Cells[1, i + 1] = dt.Columns[i].ColumnName;
range = worksheet.Cells[1, i + 1];
range.Interior.ColorIndex = 15;
range.Font.Bold = true;
}
for (var r = 0; r < dt.Rows.Count; r++)
{
for (var i = 0; i < dt.Columns.Count; i++)
{
worksheet.Cells[r + 2, i + 1] = dt.Rows[r][i].ToString();
}
rowRead++;
//is this used?
percent = ((float)(100 * rowRead)) / totalCount;
}
Microsoft.Office.Interop.Excel.Range columns = worksheet.UsedRange.Columns;
columns.AutoFit();
worksheet.Rows[1].Insert();
Excel.Range newRow = worksheet.Rows[1];
Excel.Range newCell = newRow.Cells[1];
newCell.Value = DateTime.Now.ToString("yyyy-MM-dd");
xlApp.Visible = true;
}

Categories