EPPlus是一个强大的开源库,专门用于在C#中操作Excel文件。它支持Excel 2007/2010/2013/2016的文件格式(.xlsx),提供了丰富的API来处理工作表、单元格、公式、图表等。相比传统的Microsoft.Office.Interop.Excel,EPPlus不需要安装Office软件,性能更好,特别适合在服务器端生成报表。
要开始使用EPPlus,首先需要通过NuGet安装它。在Visual Studio中,打开NuGet包管理器控制台,输入以下命令:
csharp复制Install-Package EPPlus
安装完成后,记得在代码文件顶部添加引用:
csharp复制using OfficeOpenXml;
using OfficeOpenXml.Style;
EPPlus有商业版和开源版两种授权方式。对于大多数个人和小型项目,开源版已经足够使用。在代码开始时设置授权上下文:
csharp复制ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
基础准备工作还包括了解ExcelPackage和ExcelWorksheet这两个核心类。ExcelPackage代表整个Excel文件,而ExcelWorksheet则对应文件中的单个工作表。创建它们的基本代码如下:
csharp复制using (var package = new ExcelPackage())
{
var worksheet = package.Workbook.Worksheets.Add("Sheet1");
// 在这里添加你的数据处理代码
package.SaveAs(new FileInfo(@"C:\output.xlsx"));
}
将数据导出到Excel是EPPlus最基本的功能。假设我们有一个DataTable或者List集合,需要将其内容导出到Excel中。下面是一个完整的示例:
csharp复制public void ExportToExcel<T>(List<T> data, string filePath)
{
using (var package = new ExcelPackage())
{
var worksheet = package.Workbook.Worksheets.Add("Data");
// 写入表头
var properties = typeof(T).GetProperties();
for (int i = 0; i < properties.Length; i++)
{
worksheet.Cells[1, i + 1].Value = properties[i].Name;
worksheet.Cells[1, i + 1].Style.Font.Bold = true;
}
// 写入数据
for (int i = 0; i < data.Count; i++)
{
for (int j = 0; j < properties.Length; j++)
{
worksheet.Cells[i + 2, j + 1].Value = properties[j].GetValue(data[i]);
}
}
package.SaveAs(new FileInfo(filePath));
}
}
对于DataGrid控件的导出,方法类似但需要考虑列头和绑定数据:
csharp复制public void ExportDataGridToExcel(DataGrid dataGrid, string filePath)
{
using (var package = new ExcelPackage())
{
var worksheet = package.Workbook.Worksheets.Add("Sheet1");
// 写入列头
for (int i = 0; i < dataGrid.Columns.Count; i++)
{
worksheet.Cells[1, i + 1].Value = dataGrid.Columns[i].Header;
worksheet.Cells[1, i + 1].Style.Font.Bold = true;
}
// 写入数据
for (int i = 0; i < dataGrid.Items.Count; i++)
{
for (int j = 0; j < dataGrid.Columns.Count; j++)
{
var cellValue = dataGrid.Columns[j].GetCellContent(dataGrid.Items[i]);
if (cellValue is TextBlock textBlock)
{
worksheet.Cells[i + 2, j + 1].Value = textBlock.Text;
}
}
}
package.SaveAs(new FileInfo(filePath));
}
}
要让导出的Excel看起来更专业,单元格样式设置至关重要。EPPlus提供了丰富的样式API,可以精确控制每个单元格的外观。
首先,设置字体样式:
csharp复制worksheet.Cells["A1:D1"].Style.Font.Bold = true; // 加粗
worksheet.Cells["A1:D1"].Style.Font.Size = 12; // 字号
worksheet.Cells["A1:D1"].Style.Font.Color.SetColor(Color.DarkBlue); // 字体颜色
然后是单元格填充色和边框:
csharp复制// 设置填充色
worksheet.Cells["A1:D1"].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells["A1:D1"].Style.Fill.BackgroundColor.SetColor(Color.LightGray);
// 设置边框
worksheet.Cells["A1:D10"].Style.Border.Top.Style = ExcelBorderStyle.Thin;
worksheet.Cells["A1:D10"].Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
worksheet.Cells["A1:D10"].Style.Border.Left.Style = ExcelBorderStyle.Thin;
worksheet.Cells["A1:D10"].Style.Border.Right.Style = ExcelBorderStyle.Thin;
行高和列宽的设置也很重要:
csharp复制// 设置行高
worksheet.Row(1).Height = 25; // 第一行高度为25
// 设置列宽
worksheet.Column(1).Width = 15; // 第一列宽度为15
worksheet.Column(2).AutoFit(); // 第二列自动调整宽度
对于条件格式,EPPlus也能轻松实现:
csharp复制// 添加数据条
var range = worksheet.Cells["B2:B10"];
var dataBar = range.ConditionalFormatting.AddDatabar(Color.Blue);
dataBar.ShowValue = true;
// 添加色阶
var colorScale = worksheet.Cells["C2:C10"].ConditionalFormatting.AddThreeColorScale();
colorScale.LowValue.Color = Color.Red;
colorScale.MiddleValue.Color = Color.Yellow;
colorScale.HighValue.Color = Color.Green;
在报表中插入图片可以让数据展示更加直观。EPPlus支持从文件或内存流中插入图片:
csharp复制public void InsertImage(ExcelWorksheet worksheet, string imagePath, int row, int col)
{
using (var image = new Bitmap(imagePath))
{
var picture = worksheet.Drawings.AddPicture(Guid.NewGuid().ToString(), image);
picture.SetPosition(row - 1, 0, col - 1, 0);
picture.SetSize(200, 150); // 设置图片大小
}
}
// 从字节数组插入图片
public void InsertImageFromBytes(ExcelWorksheet worksheet, byte[] imageBytes, int row, int col)
{
using (var stream = new MemoryStream(imageBytes))
{
var image = Image.FromStream(stream);
var picture = worksheet.Drawings.AddPicture(Guid.NewGuid().ToString(), image);
picture.SetPosition(row - 1, 0, col - 1, 0);
picture.SetSize(200, 150);
}
}
创建图表也很简单,EPPlus支持多种图表类型:
csharp复制var chart = worksheet.Drawings.AddChart("chart1", eChartType.ColumnClustered);
chart.SetPosition(5, 0, 5, 0);
chart.SetSize(600, 400);
// 添加数据系列
var series = chart.Series.Add(worksheet.Cells["B2:B10"], worksheet.Cells["A2:A10"]);
series.Header = "销售额";
// 设置图表标题
chart.Title.Text = "月度销售报表";
chart.Title.Font.Size = 14;
chart.Title.Font.Bold = true;
要创建真正专业的商业报表,需要结合前面介绍的各种技术。下面是一个完整的商业报表生成示例:
csharp复制public void GenerateBusinessReport(List<SalesData> salesData, string logoPath, string outputPath)
{
using (var package = new ExcelPackage())
{
var worksheet = package.Workbook.Worksheets.Add("销售报表");
// 添加公司Logo
InsertImage(worksheet, logoPath, 1, 1);
// 报表标题
worksheet.Cells["C2"].Value = "2023年度销售报告";
worksheet.Cells["C2"].Style.Font.Size = 16;
worksheet.Cells["C2"].Style.Font.Bold = true;
worksheet.Cells["C2"].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
// 合并单元格
worksheet.Cells["C2:F2"].Merge = true;
// 表头
string[] headers = { "月份", "销售额", "同比增长", "完成率" };
for (int i = 0; i < headers.Length; i++)
{
worksheet.Cells[4, i + 2].Value = headers[i];
worksheet.Cells[4, i + 2].Style.Font.Bold = true;
worksheet.Cells[4, i + 2].Style.Fill.PatternType = ExcelFillStyle.Solid;
worksheet.Cells[4, i + 2].Style.Fill.BackgroundColor.SetColor(Color.LightGray);
}
// 数据
for (int i = 0; i < salesData.Count; i++)
{
worksheet.Cells[i + 5, 2].Value = salesData[i].Month;
worksheet.Cells[i + 5, 3].Value = salesData[i].Amount;
worksheet.Cells[i + 5, 4].Value = salesData[i].GrowthRate;
worksheet.Cells[i + 5, 5].Value = salesData[i].CompletionRate;
// 设置百分比格式
worksheet.Cells[i + 5, 4].Style.Numberformat.Format = "0.00%";
worksheet.Cells[i + 5, 5].Style.Numberformat.Format = "0.00%";
}
// 添加图表
var chart = worksheet.Drawings.AddChart("salesChart", eChartType.ColumnClustered);
chart.SetPosition(5, 0, 7, 0);
chart.SetSize(800, 400);
var series1 = chart.Series.Add(worksheet.Cells["C5:C16"], worksheet.Cells["B5:B16"]);
series1.Header = "销售额";
// 设置表格边框
var dataRange = worksheet.Cells["B4:E16"];
dataRange.Style.Border.Top.Style = ExcelBorderStyle.Thin;
dataRange.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
dataRange.Style.Border.Left.Style = ExcelBorderStyle.Thin;
dataRange.Style.Border.Right.Style = ExcelBorderStyle.Thin;
// 自动调整列宽
worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();
// 保存文件
package.SaveAs(new FileInfo(outputPath));
}
}
处理大量数据时,性能优化很重要。以下是一些实用技巧:
csharp复制// 快速写入List数据
worksheet.Cells["A2"].LoadFromCollection(dataList, false);
// 快速写入DataTable
worksheet.Cells["A2"].LoadFromDataTable(dataTable, false);
csharp复制package.Workbook.CalcMode = ExcelCalcMode.Manual;
// 处理数据...
package.Workbook.CalcMode = ExcelCalcMode.Automatic;
csharp复制var namedRange = worksheet.Names.Add("SalesData", worksheet.Cells["B2:E100"]);
csharp复制using (var templateStream = new FileStream("template.xlsx", FileMode.Open))
{
using (var package = new ExcelPackage(templateStream))
{
var worksheet = package.Workbook.Worksheets["Sheet1"];
// 填充数据...
package.SaveAs(new FileInfo("output.xlsx"));
}
}
csharp复制using (var image = new Bitmap(imagePath))
{
// 插入图片...
} // 这里会自动释放图像资源
csharp复制try
{
// Excel操作代码...
}
catch (InvalidOperationException ex)
{
// 处理特定异常
}
catch (Exception ex)
{
// 处理一般异常
}
在实际项目中,我发现合理使用这些技巧可以显著提高报表生成速度,特别是在处理数千行数据和多个工作表时。