简体   繁体   中英

creating chart in an excel spreadsheet using NPOI

I know that my question will be very similar to other ones already asked on SO but as I can't find a satisfying answer, I try my luck !

Does so know whether it's possible or not to generate charts in an Excel spreadsheet using the NPOI library.

I have read that blog but it gives an example where there is already an existing template. Isn't it possible "from scratch" ?

After more investigation I got my answer here: http://npoi.codeplex.com/releases/view/19351

Unsupported Features: Excel Chart

so as explained by Leniel in his blog, we need to use a primary spreadsheet as a template.

Thanks a lot Leniel ! :)

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

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

I have found a way around this as I also had the same problem. There are not many good examples using the C# port of NPOI to generate charts. Most people I think use a template and ad then alter the result.

Depending on the chart type you need, different methodologies must be used. My examples were stolen directly from my own code that worked with 2.5.2 so defining vars like sheet may be missing so you will need to fill those in yourself.

For Bar and Line charts you can use something simple the following:

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

For Pie Charts, this got a bit more tricky as I found that the needed properties/methods were not publicly exposed. However, I was able to make this work using something like this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM