.Net创建Excel文件(插入数据、修改格式、生成图表)的方法
首先需要引用一个COM引用: Microsoft Excel 15.0 Object Library. 在程序代码中添加命名空间Microsoft.Office.Interop.Excel的引用. 然后就可以对Excel进行操作了.
<%@ WebHandler Language=”C#” Class=”EditExcel” %>
using System;
using System.Web;
using Microsoft.Office.Interop.Excel;
public class EditExcel : IHttpHandler {
public void ProcessRequest (HttpContext context) {
context.Response.Buffer = true;
//设置缓冲过期时间
context.Response.ExpiresAbsolute = DateTime.Now.AddDays(-1);
//网页不缓冲
context.Response.AddHeader(“pragma”, “no-cache”);
context.Response.AddHeader(“cache-control”, “”);
//每次访问时都会访问服务器
context.Response.CacheControl = “no-cache”;
//指定响应的 HTTP内容类型。如果未指定 ContentType,默认为TEXT/HTML
context.Response.ContentType = “application/x-excel”;
////指定文件编码
//string fileName = HttpUtility.UrlEncode(“客户资料表.xla”);
////添加http报文头输出类型
//context.Response.AddHeader(“content-disposition”, string.Format(“attachment;filename=\”{0}\””, fileName));
//创建excel文件表的标题
Application app1 = new Application();
//不可见,即后台处理
app1.Visible = false;
//Workbook book1 = app1.Workbooks.Add(Type.Missing);
//除了Add这个方法外, 如果想打开一个已经存在的表格, 并对它进行操作, 可以使用Open方法.
//app1.Workbooks.Open(TempLateName , Type.Missing ,True , Type.Missing , Type.Missing , Type.Missing , Type.Missing , Type.Missing , Type.Missing , Type.Missing , Type.Missing , Type.Missing , Type.Missing , Type.Missing , Type.Missing);
//Worksheet sheet1 = (Worksheet)book1.Sheets[1];
//Range rng1 = sheet1.get_Range(“A1”, Type.Missing);
//rng1.Value2 = “hello”;
app1.Workbooks.Add(Type.Missing);
//一般Excel默认只建一个(三个)sheet,要是多于一个(三个)sheet,只能在这额外的创建,若没新建则出错:无效索引。 (异常来自 HRESULT:0x8002000B (DISP_E_BADINDEX))
app1.Sheets.Add(Type.Missing, Type.Missing, Type.Missing,Type.Missing);
//调取工作表,直接用app1中的Worksheet,是因为默认的Workbook是Workbooks[1],也就是直接取Workbooks[1]中的Worksheets放入Application对象的Worksheets属性中。
Worksheet Sheet1 = (Worksheet)app1.Sheets[1];
//设置表名
Sheet1.Name = “表1”;
int rowCount = 20;
int colCount = 5;
object[,] dataArray = new object[rowCount, colCount];
Random rand = new Random(DateTime.Now.Millisecond);
for (int i = 0; i < rowCount; i++)
{
for (int j = 0; j < colCount; j++)
{
dataArray[i, j] = i + j;
}
}
//get_Range方法中的两个参数分别是要插入数据区域的起始和中止坐标(左上角坐标为【1,1】)。这里直接将二维数组插入表格比一点一点插入每个格子效率高些。
Sheet1.get_Range(Sheet1.Cells[1, 1], Sheet1.Cells[rowCount, colCount]).Value2 = dataArray;
//修改Excel表格样式
Range range = Sheet1.get_Range(Sheet1.Cells[2, 2], Sheet1.Cells[rowCount-1, colCount-1]);
//设置区域背景色。
range.Interior.Color = 255;
//设置字体粗体。
range.Font.Bold = true;
//设置区域边框
range.BorderAround(XlLineStyle.xlContinuous, XlBorderWeight.xlThick, XlColorIndex.xlColorIndexAutomatic, 3);
//向Excel中插入图表
// 建立图表
ChartObjects xlCharts = (ChartObjects)Sheet1.ChartObjects(Type.Missing);
//加入图表及设定大小 宽度 高度
ChartObject chartObject1 = (ChartObject)xlCharts.Add(0,0,600,300);
Chart chart1 = chartObject1.Chart;
//设置图表数据区域。
Range rangetubiao = Sheet1.get_Range(“B2”, “E10”);
// 数据表采集区域 图表类型 图例行列转换 是否显示图例 标题 X轴标题 Y轴标题
chart1.ChartWizard( rangetubiao , XlChartType.xlLine, Type.Missing, XlRowCol.xlRows, 1, 1, true , “标题”, “X轴标题”, “Y轴标题”, Type.Missing);
//如果第五和第六个参数改为2,并不是取行的第二列或列的第二行作为标题,而是取前两行或前两列,
//将图表移到数据区域之下。
chartObject1.Left = Convert.ToDouble(1);
chartObject1.Top = Convert.ToDouble(range.Top) + Convert.ToDouble(range.Height)+1;
//定义object缺省值
object missing = System.Reflection.Missing.Value;
//获取选择的工作表
Worksheet Sheet2 = (Worksheet)app1.Sheets[2];
//定义标题范围
Range searchRange = Sheet2.get_Range(“B1”, “F1”);
object[] P_obj_Items = { “苹果手机”, “技嘉主板”, “福喜家园奶糖”, “桥牌麻将”, “果子狸酒杯” };
//绘制标题
searchRange.set_Value(missing, P_obj_Items);
//设置字体加粗
searchRange.Font.Bold = true;
//设置字体样式
searchRange.Font.Name = “宋体”;
//设置字体大小
searchRange.Font.Size = 10;
//设置标题对齐方式
searchRange.HorizontalAlignment = XlHAlign.xlHAlignCenter;
//获得要生成图表的数据
for (int i = 0; i < 13; i++)
{
Sheet2.Cells[2 + i, 1] = i;
Sheet2.Cells[2 + i, 2] = i + 1;
Sheet2.Cells[2 + i, 3] = i + 2;
Sheet2.Cells[2 + i, 4] = i + 3;
Sheet2.Cells[2 + i, 5] = i + 4;
}
// 建立图表
ChartObjects Chart2 = (ChartObjects)Sheet2.ChartObjects(Type.Missing);
//加入图表及设定大小 宽度 高度
ChartObject chartObject2 = (ChartObject)Chart2.Add(0, 0, 600, 300);
Chart chart2 = chartObject2.Chart;
//实例化Excel绘图对象
//Chart chart = (Chart)book1.Charts.Add(missing, missing, missing, missing);
Range chartRange = Sheet2.get_Range(“A1:A14”, “B1:E14”);//定义绘制图表范围
//在指定范围绘制图表
chart2.ChartWizard(chartRange, XlChartType.xl3DColumn, missing, XlRowCol.xlColumns, 1, 1, true, “多糖商品销量分析”, “月份”, “销量”, missing);
//将图表移到数据区域之下。
chartObject2.Left = Convert.ToDouble(1);
chartObject2.Top = Convert.ToDouble(chartRange.Top) + Convert.ToDouble(chartRange.Height);
//设置保存Excel时不显示对话框
//app1.DisplayAlerts = false;
//保存工作簿
//book1.Save();
//关闭工作簿
//book1.Close(false, missing, missing);
//保存前,需要先刷新,使新的记录能被记下
Workbook workBook = app1.Workbooks[1];
workBook.RefreshAll();
//之后的保存,也有两种方法
//1.直接保存,当之前通过Open方法创建Excel文件,并没有设为只读时,可以用这种方法,比较简单
//workBook.Save();
//2.这一种方法的比较灵活,就是SaveAs(),相当于界面操作的另存为,但这个方法的问题和创建Workbook时的第一种方法一样,参数比较多,虽然大部分可以用miss
// 文件名
workBook.SaveAs(“文件.xlsx”, missing, missing, missing, missing, missing, XlSaveAsAccessMode.xlNoChange, missing, missing, missing, missing, missing);
//保存之后要关闭WorkBook
workBook.Close(false, missing, missing);
workBook = null;
//最后需要清空内存
app1.Quit();
app1 = null;
GC.Collect();
}
public bool IsReusable {
get {
return false;
}
}
}
获取区域值的方法, 返回的是一个Object类型的数组:
1
2
3
4
5
6
|
sheet1.get_Range( "B2" , Type.Missing); //返回B2单元格
sheet1.get_Range( "A1:C10" , Type.Missing); //返回左上角A1到右下角C10区域单元格
sheet1.get_Range( "A1" , "C10); //和上一行效果一样(左上角A1到右下角C10区域单元格)
sheet1.get_Range( "A:A" , Type.Missing); //返回整个A列
sheet1.get_Range( "A:C" , Type.Missing); //返回A到C列
sheet1.get_Range( "3:3" , Type.Missing); //返回A到C列
sheet1.get_Range( "A1:A5, C1:C5" , Type.Missing); //返回两个独立的区域
|
除了获取一个区域的值, 获得单个单元格值的方法:
1
2
|
Range rng1 = (Range)sheet1.Cells[1, 1]; //获取A1单元格
Range rng2 = (Range)sheet1.Cells[3, "C]; //获取C3单元格
Range rng3 = (Range)sheet1.Cells[2, Type.Missing]; //获取B1单元格
|
Range对象除了Value2属性, 还有Value属性, 只有当涉及日期和货币格式才使用这个属性. 否则, 为保持程序简洁和一致性, 应该使用Value2属性.
Range对象还有个只读属性: Text, 该属性虽然是Object类型的, 但所有值类型都是按文本方式进行处理的. 所以在使用这个Text属性时, 如果已经确定这个文本的数据类型时, 可以使用Parse方法把文本转变成该数据类型. 如果不能确定, 则可以使用TryParse方法.
除此之外, Range对象中如果某个或某些单元格的值全为数字, 而我们不想按数字来处理这些值, 想把它转变成文本或是其它格式. 可以使用Range的NumberFormat属性.