asp.net下NPOI生成Excel使用心得

        之前一直是用sql文查询数据完了手动粘贴在Excel文件里,虽然也用不了多少时间,但对于我这种懒人来说确实比较麻烦,于是乎就着手于将这部分工作交由代码完成,我们只用动动手指点两个按钮便可完成,何乐而不为呢?

        本来想用Spire来着,之前也用过效果不错。看了看项目里已经引用NPOI了,那就勉为其难重新学习一下吧,毕竟一个项目里有两个导出库多少有点不合适。

        表格填充

        表格填充就比较简单了

        1. 创建一个文件薄 var wb = new XSSFWorkbook();

        2. 创建表单var sheet = wb.CreateSheet("xxxx");

        3. 创建行var row= sheet.CreateRow(0);

        4. 创建单元格var cell = row.CreateCell(0);

        可以通过row.Height = 400 来配置单元格的行高;

        sheet下面有sheet.SetColumnWidth(0, 4000)方法可以配置列宽,第一个参数是列号,第二个参数是列宽。

        cell的话可以通过cell.CellStyle属性自定义每个单元格的样式,style下有很多方法可以用,也可以配置font调整单元格字体,format调整单元格显示格式。cell.SetCellValue()来设置单元格的值。 

        style.Alignment = HorizontalAlignment.Left;//文字水平对齐方式
        style.VerticalAlignment = VerticalAlignment.Center;//文字垂直对齐方式

        //设置边框
        style.BorderBottom = BorderStyle.Thin;
        style.BorderLeft = BorderStyle.Thin;
        style.BorderRight = BorderStyle.Thin;
        style.BorderTop = BorderStyle.Thin;
        style.WrapText = true;自动换行

        style.FillForegroundColor = HSSFColor.White.Index;设置单元格背景色
        style.FillPattern = FillPattern.SolidForeground;设置背景颜色时一定要与这个方法一起使用,否则没有效果

        //字体
        var font= wb.CreateFont();
        font.FontName = "楷体";
        font.Color = HSSFColor.Red.Index;//字体颜色
        font.Boldweight = (short)FontBoldWeight.Normal;//字体加粗样式
        font.FontHeight = 200;
        style.SetFont(font);//样式里的字体设置具体的字体样式

        var dataFormatCustom = wb.CreateDataFormat();
        dateStyle.DataFormat = dataFormatCustom.GetFormat("yyyy-MM-dd HH:mm:ss");

        还有一个合并单元格的方法,四个参数分别是起始行号,结束行号,起始列号,结束列号。

        sheet.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(x1, x2, y1, y2));

        

        生成图表

        生成图表个人感觉不是特别好用,有些spire支持的属性在这边不能修改,不知道是不是我用的NPOI版本太低了,我先把功能做好,这个等以后有空了再研究。

        图表还是再sheet下生成的,首先拿到绘图工具,

        var drawing = sheet.CreateDrawingPatriarch();

        然后通过绘图工具把锚点创建出来,大概意思就相当于是你这个图表的四个角在那个位置。前面四个参数是偏移量,我这个需求不涉及这个我就填0了,后面4个参数分别代表开始的列号,开始的行号,结束的列号,结束的行号。
        var anchor = drawing.CreateAnchor(0, 0, 0, 0, col1, row1, col2,row2)

        锚点创建好后,还是通过绘图工具把图表创建出来。

        var chart = drawing.CreateChart(anchor);

         var chart = drawing.CreateChart(anchor) as XSSFChart;
        //生成图例,就是图表中每一根线条代表了什么意思
        var legend = chart.GetOrCreateLegend();
        //图例位置
        legend.Position = LegendPosition.Top;

        //图表,生成图表的方法有两个泛型,第一个泛型代表的是标题列的数据类型,第二个轴代表的是数据列的数据类型。
        var data = chart.ChartDataFactory.CreateLineChartData<string, double>();

        // X轴Y轴.,x轴可以调整为在图表的上方或下方,Y轴可以调整为在图表的左边或右边
        var bottomAxis = chart.ChartAxisFactory.CreateCategoryAxis(AxisPosition.Bottom) as XSSFCategoryAxis;
        IValueAxis leftAxis = chart.ChartAxisFactory.CreateValueAxis(AxisPosition.Left);

        //通过设置AxisCrossBetween.Between可以解决图表图表坐标轴位置在刻度线上还是在刻度线之间的问题。
        leftAxis.SetCrossBetween(AxisCrossBetween.Between);

        //标题列和数据列也是通过range的方法从sheet里面获取的,这跟合并单元格的方法差不多。标题列可以是字符串也可以选择数字
        IChartDataSource<string> xs = DataSources.FromStringCellRange(sheet, new CellRangeAddress(firstRow, endRow, titleCol, titleCol));

        //数据列泛型必须是int,double等数字类型,而且只能通过FromNumericCellRange方法获取
        IChartDataSource<double> ys1 = DataSources.FromNumericCellRange(sheet, new CellRangeAddress(firstRow, endRow, dataCol, dataCol));

        //数据系列,每个图表里面可以加多个系列,可以显示多根线条,需要通过serial.SetTitle(title);的方法配置每个系列的名称,图例也会相应的增加。
        var serial = data.AddSeries(xs, ys1);
        serial.SetTitle(title);
        chart.Plot(data, bottomAxis, leftAxis);

        数据列需要注意的是在cell.SetCellValue()需要传int 或double的值进去,不可以直接传string的值,不然他内部不会给你自动解析,图表就显示不出来。

        Plot方法调完图表就创建好了,创建出来大概像是这样的。        

        柱状图跟折线图比较类似,唯一一点区别就是用CreateBarChartData来创建

        var data = chart.ChartDataFactory.CreateBarChartData<string, double>();

        饼图

        这个NPOI貌似并不支持,为了完成目标,只能用代码生成图片替代了,虽然不能编辑,但也像那么回事。

private static Bitmap GetPieGraphic(int width, int height, string name, float[] data, string[] titles, Color[] colors){

                string familyName = "Arial";

                //根据宽高生成Bitmap
                Bitmap objbitmap = new Bitmap(width, height);
                Graphics objgraphics = Graphics.FromImage(objbitmap);
                objgraphics.Clear(Color.White);

                //一些关于图片质量的设置
                objgraphics.SmoothingMode = SmoothingMode.HighQuality; 
                objgraphics.CompositingQuality = CompositingQuality.HighQuality;
                objgraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                objgraphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
                //定位饼图相对于图片的位置,前两位为起始的x,y坐标,后两位为饼图的宽高
                Rectangle rect = new Rectangle(width / 5,  height / 5, 1300, 1500);
                float currentdegree = 0.0f;
                float Total = data.Sum();

                //这便是绘制饼图的标题,PointF为字符串的位置x,y
                objgraphics.DrawString(name, new Font(familyName, 40), Brushes.Black, new PointF(800, 100));
                for (int i = 0; i < data.Length; i++)
                {
                    Color temC = colors[i];
                    SolidBrush brush = new SolidBrush(temC);
                    objgraphics.FillPie(brush, rect, currentdegree, Convert.ToSingle(data[i] / Total * 360));
                    currentdegree += Convert.ToSingle(data[i] / Total * 360);
                }
                //放置图例 ,第一个图例的起始位置x,y
                PointF basePoint = new PointF(32, 64);
                //图例色块的大小 
                SizeF theSize = new SizeF(80, 48);
                //第一个色块的说明文字的位置          

                PointF textPoint = new PointF(basePoint.X + 120, basePoint.Y);
                for (int j = 0; j < data.Length; j++)
                {
                    RectangleF baseRectangle = new RectangleF(basePoint, theSize);
                    //画代表色块             

                    objgraphics.FillRectangle(new SolidBrush(colors[j]), baseRectangle);
                    var temstr = string.Format("{0}%", (data[j] / Total * 100).ToString("#0.00"));
                    objgraphics.DrawString(titles[j] + "  " + temstr, new Font(familyName, 24), Brushes.Black, textPoint);
                    basePoint.Y += 64;
                    textPoint.Y += 64;
                }
                return objbitmap;

}

生成出来的饼图大概长这样,颜色,位置什么的可以自己diy,这个就无需多言了。

 

        到这里基本需求就实现好了,但还有下面几个问题没有解决,

        1. 折线图是带弧度的,不知道Excel里面这个平滑线的属性如何去掉        
        

        2. NPOI里面不能给图表设置标题,看了chart里面有一个title字段,但是是只读字段,不知道如何修改。

         如果有哪位朋友恰巧研究过这2个问题,拜托一定留言,感谢了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值