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

问题描述 投票:0回答:5

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

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

我读过 blog 但它给出了一个已经存在模板的示例。难道“从头开始”不可能吗?

c# excel charts npoi
5个回答
7
投票

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

不支持的功能:Excel 图表

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

非常感谢莱尼尔! :)


1
投票

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


1
投票

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


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 );
}

0
投票

Romias 说得对! “现在可以使用 NPOI:github.com/tonyqus/npoi/blob/master/examples/xssf/LineChart/...”

2010年可能没有可能,现在肯定有可能。这是我的经验,我可以创建折线图和 XY 图表。

示例位于源代码的“testcases\ooxml\XSSF\UserModel\Charts”文件夹中。例如。 “TestXSSFScatterChartData.cs”是我最喜欢的XY图表。

下载地址:https://github.com/nissl-lab/npoi

© www.soinside.com 2019 - 2024. All rights reserved.