使用NPOI在Excel电子表格中创建图表

时间:2010-03-05 10:09:50

标签: c# excel charts npoi

我知道我的问题与已经问过的其他问题非常相似,但由于我找不到令人满意的答案,我试试运气!

是否知道是否可以使用NPOI库在Excel电子表格中生成图表。

我已经阅读了blog,但它提供了一个已有模板的示例。难道不是“从头开始”吗?

4 个答案:

答案 0 :(得分:7)

经过更多调查后,我在这里得到了答案:http://npoi.codeplex.com/releases/view/19351

  

不支持的功能:Excel图表

正如Leniel在他的博客中所解释的那样,我们需要使用主电子表格作为模板。

非常感谢Leniel! :)

答案 1 :(得分:1)

创建没有自动化的图表的另一个解决方案是使用第三方组件,例如这个SmartXLS for .Net,它可以从头开始创建图表/数据透视表。

答案 2 :(得分:1)

对于带有图表的NPOI示例,请参阅:http://www.zachhunter.com/2010/05/npoi-excel-template/

答案 3 :(得分:0)

我找到了解决方法,因为我也遇到了同样的问题。使用NPOI的C#端口生成图表的好例子并不多。我认为大多数人使用模板和广告然后改变结果。

根据您需要的图表类型,必须使用不同的方法。我的示例是直接从我自己的代码中窃取的,该代码适用于 2.5.2,因此可能会缺少像 sheet 这样的变量定义,因此您需要自己填写。

对于条形图和折线图,您可以使用以下简单的方法:

    IDrawing drawing = sheet.CreateDrawingPatriarch ( );
/* Define anchor points in the worksheet to position the chart */
IClientAnchor anchor = drawing.CreateAnchor ( 0, 0, 0, 0, 0, 3, 10, 23 );
row = row + 23;
/* Create the chart object based on the anchor point */
IChart barChart = drawing.CreateChart ( anchor );
/* Define legends for the line chart and set the position of the legend */
IChartLegend legend = barChart.GetOrCreateLegend ( );
legend.Position = LegendPosition.Bottom;
/* Create data for the chart */
IBarChartData<double, double> data = barChart.ChartDataFactory.CreateBarChartData<double, double> ( );
/* Define chart AXIS */
IChartAxis bottomAxis = barChart.ChartAxisFactory.CreateCategoryAxis ( AxisPosition.Bottom );
IValueAxis leftAxis = barChart.ChartAxisFactory.CreateValueAxis ( AxisPosition.Left );
leftAxis.Crosses = AxisCrosses.AutoZero;

/* Define Data sources for the chart */
/* Set the right cell range that contain values for the chart */
/* Pass the worksheet and cell range address as inputs */
/* Cell Range Address is defined as First row, last row, first column, last column */
int iDataPoints = dataSet.Tables[ "_CHART" ].Rows.Count + 1;

//Defines the rows/columns used for X-Axis data
IChartDataSource<double> xs = DataSources.FromNumericCellRange ( sheetChart, new CellRangeAddress ( 2, iDataPoints, 0, 0 ) );
//Defines the rows/columns used for the line data
IChartDataSource<double> ys1 = DataSources.FromNumericCellRange ( sheetChart, new CellRangeAddress ( 2, iDataPoints, 1, 1 ) );
/* Add chart data sources as data to the chart */
data.AddSeries ( xs, ys1 );

/* Plot the chart with the inputs from data and chart axis */
barChart.Plot ( data, new IChartAxis[] { bottomAxis, leftAxis } );

对于饼图,这变得有点棘手,因为我发现所需的属性/方法没有公开。但是,我能够使用这样的东西来完成这项工作:

    /* At the end of this step, we have a worksheet with test data, that we want to write into a chart */
/* Create a drawing canvas on the worksheet */
IDrawing drawing = sheet.CreateDrawingPatriarch ( );
/* Define anchor points in the worksheet to position the chart */
IClientAnchor anchor = drawing.CreateAnchor ( 0, 0, 0, 0, 0, 3, 10, 23 );
row = row + 23;
/* Create the chart object based on the anchor point */
IChart pieChart = drawing.CreateChart ( anchor );

XSSFChart xssfChart = (XSSFChart) pieChart;

MethodInfo dynMethod = xssfChart.GetType ( ).GetMethod ( "GetCTChart", BindingFlags.NonPublic | BindingFlags.Instance );
object oCTChart = dynMethod.Invoke ( xssfChart, null );
CT_Chart ctChart = (CT_Chart) oCTChart;


//CT_PlotArea plotArea = xssfChart.GetCTChart ( ).plotArea == null ? xssfChart.GetCTChart ( ).AddNewPlotArea ( ) : xssfChart.GetCTChart ( ).plotArea;
CT_PlotArea plotArea = ctChart.plotArea == null ? ctChart.AddNewPlotArea ( ) : ctChart.plotArea;
//plotArea.
var ctpieChart = plotArea.AddNewPie3DChart ( );

//CT_Pie3DChart ctpieChart = plotArea.AddNewPie3DChart ( );


CT_Boolean bVaryColor = new CT_Boolean ( );
bVaryColor.val = 1;
ctpieChart.varyColors = bVaryColor; // .AddNewVaryColors ( ).val = 1;// addNewVaryColors ( ).setVal ( true );
                                    //xssfChart. ( this.title );


IChartDataSource<double> xs = DataSources.FromNumericCellRange ( sheetChart, new CellRangeAddress ( 2, iDataPoints, 0, 0 ) );
//Defines the rows/columns used for the line data
IChartDataSource<double> ys1 = DataSources.FromNumericCellRange ( sheetChart, new CellRangeAddress ( 2, iDataPoints, 1, 1 ) );

String axisDataRange = new CellRangeAddress ( 2, iDataPoints, 0, 0 ).FormatAsString ( sheetChart.SheetName, true );
String numDataRange = new CellRangeAddress ( 2, iDataPoints, 1, 1 ).FormatAsString ( sheetChart.SheetName, true );


CT_UnsignedInt uIval = new CT_UnsignedInt ( );
uIval.val = 0;

//Pie Chart Series
ctpieChart.ser = new List<CT_PieSer> ( );
CT_PieSer ser = new CT_PieSer ( ); //.AddNewSer ( );

ser.idx = uIval;
ser.order = uIval;

//Create category section
ser.cat = new CT_AxDataSource ( );
ser.cat.strRef = new CT_StrRef ( );
ser.cat.strRef.strCache = new CT_StrData ( );
ser.cat.strRef.f = axisDataRange;
CT_UnsignedInt uIRange = new CT_UnsignedInt ( );
uIRange.val = (uint) dataSet.Tables[ "_CHART" ].Rows.Count;
ser.cat.strRef.strCache.ptCount = uIRange;

//Create value section
ser.val = new CT_NumDataSource ( );
ser.val.numRef = new CT_NumRef ( );
ser.val.numRef.f = numDataRange;
ser.val.numRef.numCache = new CT_NumData ( );
ser.val.numRef.numCache.formatCode = "General";
ser.val.numRef.numCache.ptCount = uIRange;

//Create Pts array
ser.dPt = new List<CT_DPt> ( );

//Create Category Pts
ser.cat.strRef.strCache.pt = new List<CT_StrVal> ( );

//Create Value Pts
ser.val.numRef.numCache.pt = new List<CT_NumVal> ( );

//Create Chart Styles/Settings
ser.dLbls = new CT_DLbls ( );
ser.dLbls.spPr = new CT_ShapeProperties ( );
ser.dLbls.spPr.noFill = new NPOI.OpenXmlFormats.Dml.CT_NoFillProperties ( );
ser.dLbls.spPr.ln = new NPOI.OpenXmlFormats.Dml.CT_LineProperties ( );
ser.dLbls.spPr.ln.noFill = new NPOI.OpenXmlFormats.Dml.CT_NoFillProperties ( );
ser.dLbls.showSerName = new CT_Boolean ( ) { val = 0 };
ser.dLbls.showPercent = new CT_Boolean ( ) { val = 0 };

//Add the series
ctpieChart.ser.Add ( ser );

//Loop through points and add to arrays
for ( int iPt = 0; iPt < dataSet.Tables[ "_CHART" ].Rows.Count; iPt++ )
{
    CT_UnsignedInt uIPt = new CT_UnsignedInt ( );
    uIPt.val = (uint) iPt;

    //Create Pt
    CT_DPt oPt = new CT_DPt ( );
    oPt.idx = uIPt;
    ser.dPt.Add ( oPt );

    //Create Label Pt
    CT_StrVal cPt = new CT_StrVal ( );
    cPt.idx = (uint) iPt;
    cPt.v = dataSet.Tables[ "_CHART" ].Rows[ iPt ][ "Label" ].ToString ( );
    ser.cat.strRef.strCache.pt.Add ( cPt );

    //Create Value Pt
    CT_NumVal vPt = new CT_NumVal ( );
    vPt.idx = (uint) iPt;
    vPt.v = dataSet.Tables[ "_CHART" ].Rows[ iPt ][ "Value" ].ToString ( );
    ser.val.numRef.numCache.pt.Add ( vPt );
}