通用 DataGridView 导出到 Excel (带主题和格式)
一篇关于将任何 datagridview 内容导出到 Excel 文件,并带有主题和格式化或 *.CSV (无主题) 的文章

引言
这是我对带主题和格式化的通用 DataGridView 导出到 Excel 的第二次也是最后一次更新。
总而言之,它的重点是创建一个支持一些格式化的动态和通用的导出解决方案。
我增加了 4 个额外的的主题,一些额外的条件和对齐功能。 我还添加了直接导出到 Excel 的功能,没有中间的 CSV。 我将只关注新的内容。
修复了用于 CSV 导出的非欧盟/美国文化的的问题。 现在它在 CSVToExcel()
方法中使用 System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator 代替 ","。 还修复了具体的数字格式 rrr.NumberFormat = "#,##0.00 [$€-407]";,使用更通用的 rrr.NumberFormat = String.Format("#,##0.00 [$€]");
对于这些精彩的观察,你要感谢 Mike.
现在,它有 4 个新主题,总共有八个
- 蓝天 - 旧
- 经典灰 - 旧
- 绿是好的 - 旧
- 可爱紫 - 旧 (从 SweetViolet 重命名)
- 甜粉色 - 新
- 红衣女郎 - 新
- 橙色 - 新
- 深蓝色 - 新
添加了一个额外的条件 -> TEXT,这对于同时包含数字和文本/字符串数据的列很有用。 还添加了一个新的 Enum Align。
- 4 种货币格式(欧元和美元,带 2 位和 4 位小数)
- 2 种百分比(默认情况下为 2 位和 4 位小数)
- 3 个数字条件(带 2、3 或 4 位小数)
- 2 个日期时间条件(一个采用 mm/dd/yy 格式,另一个采用 dd/mm/yy 格式)
- 文本格式
- 4 个(实际上是 3 个)对齐条件(左对齐、右对齐、居中对齐和默认的无对齐)
为了运行该应用程序,您需要从 COM 选项卡添加对 Microsoft Excel 11.0 或 12.0 对象库的引用。 警告:在 12.0 (2007) 版本中,颜色有所不同,因此输出可能不是您想要的。 您需要先进行测试。
特别感谢 PeterMoon 在 将 DataSet 快速导出到 Excel 文章中的想法。
Using the Code
使用代码非常简单。 导出实用程序有三个类:主类 GenericFormattedExcel2003Export
和辅助类 ColumnCondition
和 ColumnRowConditon
。 该实用程序还具有 4 个 enum
s:Condition
、Theme
和 ThemeColors
。
下面给出了这三个 enum
s
public enum Condition
{
None, //default(no condition)
Numeric, //2 digits
Numeric3, //3 digits
Numeric4, //4 digits
Percentage, //2 digits
Percentage4, //4 digits
CurrencyEuro, //2 digits
CurrencyEuro4, //4 digits
CurrencyDollar, //2 digits
CurrencyDollar4,//4 digits
DateTime, //dd/mm/yyyy
USDateTime, //mm/dd/yyy
Text
}
public enum Theme
{
BlueSky,
ClassicGray,
GreenIsGood,
NiceViolet,
DarkBlue,//new
SweetPink,//new
LadyInRed,//new
OrangeWorks,//new
CSV//no theme and a lot faster *.CSV export
}
public enum ThemeColors
{
//first row FontColor is WHITE for all the themes
FirstRowFontColor = 2,
//the BlueSkyColors
BlueSkyFirstRowInteriorColor = 11,
BlueSkyInteriorColor = 37,
BlueSkyFontColor = 11,
//the ClassicGrayColors
ClassicGrayFirstRowInteriorColor = 48,
ClassicGrayInteriorColor = 15,
ClasicGaryFontColor = 56,
//the GreenIsGoodColors
GreenIsGoodFirstRowInteriorColor = 50,
GreenIsGoodInteriorColor = 35,
GreenIsGoodFontColor = 10,
//the SweetViolet/PinkColors for the ladies:)
NiceVioletFirstRowInteriorColor = 13,
NiceVioletInteriorColor = 39,
NiceVioletFontColor = 13,
//the OrangwWorks colors
OrangeWorksFirstRowInterior = 46,
OrangeWorksFont = 53,
OrangeWorksInterior = 40,
//the SweetPink colors
SweetPinkFirstRowInterior = 7,
SweetPinkFont = 13,
SweetPinkInterior = 38,
//the LadyInRed colors
LadyInRedFirstRow = 3,
LadyInRedFont = 3,
LadyInRedInterior = 38,
//the DarkBlue colors
DarkBlueFirstRow = 55,
DarkBlueFont = 11,
DarkBlueInterior = 47
}
在一个小测试应用程序中使用代码。 首先,我们需要向 datagridview
添加一些数据。 对于此任务,我创建了一个名为 SomethingReallyReallyUseless
的虚拟示例类。

//a dummy class to load some data into the gridview
public class SomethingReallyReallyUseless
{
private string name;
private double sum = 0.00d;
private double performance = 0.00d;
public string Name
{
get { return name; }
set { name = value; }
}
public double Sum
{
get { return sum; }
set { sum = value; }
}
public double Performance
{
get { return performance; }
set { performance = value; }
}
}
ColumnConditions
类
public class ColumnConditions
{
private int column = 0;
private Conditon condition = Conditon.None;
private Align align = Align.None;
public int Column
{
get { return column; }
set { column = value; }
}
public Conditon Cond
{
get { return condition; }
set { condition = value; }
}
public Align Alignment
{
get { return align; }
set { align = value; }
}
}
使用 DarkBlue 主题以及列和行额外的条件。 首先,我们必须创建条件,然后将它们传递给 GenericFormattedExcel2003Export
private void button1_Click(object sender, EventArgs e)
{
string mode = rCsv.Checked ? "CSV" : "XLS";
List<MyExcelExport.ColumnConditions> conds =
new List<MyExcelExport.ColumnConditions>();
MyExcelExport.ColumnConditions curr = null;
//create the column conditions
//no need to specify alignment
//only if you wish/needed. It defaults to MyExcelExport.Align.None
curr = new MyExcelExport.ColumnConditions();
curr.Column = 2;
curr.Cond = MyExcelExport.Conditon.CurrencyEuro;
conds.Add(curr);
//specify Alignment
curr = new MyExcelExport.ColumnConditions();
curr.Column = 3;
curr.Cond = MyExcelExport.Conditon.Percentage;
curr.Alignment = MyExcelExport.Align.Right;
conds.Add(curr);
List<MyExcelExport.ColumnRowConditon> rowConds =
new List<MyExcelExport.ColumnRowConditon>();
MyExcelExport.ColumnRowConditon row = new MyExcelExport.ColumnRowConditon();
row.Column = 1;
row.ConditionValue = "Total";
rowConds.Add(row);
try
{
MyExcelExport.GenericFormattedExcel2003Export gExp =
new MyExcelExport.GenericFormattedExcel2003Export(mode, dataGridView1,
MyExcelExport.Theme.DarkBlue, conds, rowConds, null);
}
catch (COMException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
使用 DarkBlue 主题,无额外条件。
private void button1_Click(object sender, EventArgs e)
{
string mode = rCsv.Checked ? "CSV" : "XLS";
try
{
MyExcelExport.GenericFormattedExcel2003Export gExp =
new MyExcelExport.GenericFormattedExcel2003Export(dataGridView1,
MyExcelExport.Theme.BlueSky, conds, rowConds);
}
catch (COMException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
最后,使用 PeterMoon 的想法,从 GenericFormattedExcel2003Export
类中导出到 Blue Sky 主题的更新后的代码示例
//this is PeterMoon's idea-> to use Range.Value2 property
//and paste a bi dimensional array of objects/datas
//creates the two dimensional object[,] from the datagridview
private object[,] CreateTwoDimensionalObject()
{
object[,] datas = new object[dgv.Rows.Count + 1, dgv.Rows[0].Cells.Count];
//add the first row(the column headers) to the array
for (int col = 0; col < dgv.Columns.Count; col++)
{
datas[0, col] = dgv.Columns[col].HeaderText;
}
//copy the actual datas
for (int col = 0; col < dgv.Rows[0].Cells.Count; col++)
{
for (int row = 0; row < dgv.Rows.Count; row++)
{
datas[row + 1, col] = dgv.Rows[row].Cells[col].Value.ToString();
}
}
return datas;
}
//exports in the blue sky theme
private void BlueSky()
{
try
{
object[,] datas = CreateTwoDimensionalObject();
object None = Type.Missing;
Excel.Application app = new Microsoft.Office.Interop.Excel.Application();
app.Visible = true;
Excel.Workbook wk = app.Workbooks.Add(None);
Excel.Worksheet ws = (Excel.Worksheet)wk.ActiveSheet;
Excel.Range upperLeft = (Excel.Range)ws.Cells[1, 1];
Excel.Range rightLimit = upperLeft.get_Offset(0, dgv.Columns.Count - 1);
Excel.Range bottomRight = rightLimit.get_Offset(dgv.Rows.Count, 0);
Excel.Range wholeThing = ws.get_Range(upperLeft, bottomRight);
wholeThing.Value2 = datas;
//set the font color
wholeThing.Font.ColorIndex = ThemeColors.BlueSkyFontColor;
//create the borders
wholeThing.Borders.Weight = Excel.XlBorderWeight.xlThin;
wholeThing.Borders.LineStyle = Excel.XlLineStyle.xlContinuous;
wholeThing.Borders.ColorIndex = Excel.XlColorIndex.xlColorIndexAutomatic;
//format first row
upperLeft.EntireRow.Font.Bold = true;
upperLeft.EntireRow.Font.Italic = true;
upperLeft.EntireRow.Font.ColorIndex = ThemeColors.FirstRowFontColor;
ws.get_Range(upperLeft, rightLimit).Interior.ColorIndex =
ThemeColors.BlueSkyFirstRowInteriorColor;
Excel.Range r;
//set the auto fit for each column
for (int i = 1; i <= dgv.Rows[0].Cells.Count; i++)
{
r = (Excel.Range)ws.Cells[1, i];
r.EntireColumn.AutoFit();
}
//color the 3rd row
r = (Excel.Range)ws.Cells[3, 1];
rightLimit = r.get_End(Microsoft.Office.Interop.Excel.XlDirection.xlToRight);
ws.get_Range(r, rightLimit).Interior.ColorIndex =
ThemeColors.BlueSkyInteriorColor;
//get the second and third row
r = (Excel.Range)ws.Cells[2, 1];
bottomRight = r.get_Offset(1, 0);
bottomRight = bottomRight.get_End
(Microsoft.Office.Interop.Excel.XlDirection.xlToRight);
//copy the range
ws.get_Range(r, bottomRight).Copy(None);
//get the whole range
r = (Excel.Range)ws.Cells[4, 1];
bottomRight = r.get_End(Microsoft.Office.Interop.Excel.XlDirection.xlToRight);
bottomRight = bottomRight.get_End
(Microsoft.Office.Interop.Excel.XlDirection.xlDown);
wholeThing = ws.get_Range(r, bottomRight);
//now paste special -> formats
wholeThing.PasteSpecial(Microsoft.Office.Interop.Excel.XlPasteType.xlPasteFormats,
Microsoft.Office.Interop.Excel.XlPasteSpecialOperation.
xlPasteSpecialOperationNone, false, false);
//apply column formatting, if any
ApplyColumnFormats(ws);
//apply rowcolumn(Bold row) formatting, if any
if ((this.rowConds != null) && (this.rowConds.Count > 0))
{
Excel.Range rrr = null;
//pass each datagridview row only once
foreach (DataGridViewRow dgvItem in dgv.Rows)
{
foreach (var rowCon in rowConds)
{
if (dgvItem.Cells[rowCon.Column - 1].Value.ToString().Equals
(rowCon.ConditionValue))
{
rrr = (Excel.Range)ws.Cells[dgvItem.Cells[0].RowIndex + 2,
dgvItem.Cells[rowCon.Column - 1].ColumnIndex + 1];
rrr.EntireRow.Font.Bold = true;
}
}
}
}
//select cell A1
upperLeft.Select();
}
catch (COMException ex)
{
throw ex;
}
catch (Exception ex)
{
throw ex;
}
}
关注点
写这篇文章很愉快。 我将停止修改/添加文章的功能。 我可以添加大量新功能,但这不是本文的目的。 您可以修改并添加您自己的额外条件/格式化/或其他任何内容。 希望它能帮助到某人。 BRB 带来 2007 (Excel) 的额外酷炫主题/颜色和其他东西。
历史
- 2009 年 10 月 30 日:这是第二次也是最后一次更新。
祝您编码愉快