Use values outside excel cell in apache poi Bar chart

Masum

I am trying to create a bar chart in excel file using Apache poi and following the code mentioned here: Create Bar Chart in Excel with Apache POI.

In my case, I need to use data values coming from a different source instead of the excel cells. How can I use those values in the BarChart?

Assume that the values will come as an array of float/double values. Also, I need to be able to set Bar colors independently. For example, some bars will be green while some others will be red.

I modified the data portion of Create Bar Chart in Excel with Apache POI code in the following manner:

 CTBarSer ctBarSer = ctBarChart.addNewSer();
 CTSerTx ctSerTx = ctBarSer.addNewTx();
 CTStrRef ctStrRef = ctSerTx.addNewStrRef();
ctStrRef.setF("hardcoded" + r);
ctBarSer.addNewIdx().setVal(r-2);
CTAxDataSource cttAxDataSource = ctBarSer.addNewCat();
CTStrData ctStrData = cttAxDataSource.addNewStrLit();
ctStrData.addNewPt().setV("Val1");
ctStrData.addNewPt().setV("Val2");
ctStrData.addNewPt().setV("Val3");

CTNumDataSource ctNumDataSource = ctBarSer.addNewVal();

CTNumData ctNumData = ctNumDataSource.addNewNumLit();
CTNumVal ctNumVal = ctNumData.addNewPt();
ctNumVal.setV(String.valueOf(0.92));

ctNumData = ctNumDataSource.addNewNumLit();
ctNumVal = ctNumData.addNewPt();
ctNumVal.setV(String.valueOf(0.95));

ctNumData = ctNumDataSource.addNewNumLit();
ctNumVal = ctNumData.addNewPt();
ctNumVal.setV(String.valueOf(0.98));

Any help is greatly appreciated. Thanks!

When I output the excel file using print, it gives the following result:

<xml-fragment xmlns:char="http://schemas.openxmlformats.org/drawingml/2006/chart" xmlns:main="http://schemas.openxmlformats.org/drawingml/2006/main">
  <char:plotArea>
    <char:layout/>
    <char:barChart>
      <char:barDir val="col"/>
      <char:varyColors val="false"/>
      <char:ser>
        <char:idx val="0"/>
        <char:tx>
          <char:strRef>
            <char:f>hardcoded2</char:f>
          </char:strRef>
        </char:tx>
        <char:spPr>
          <main:ln>
            <main:solidFill>
              <main:srgbClr val="000000"/>
            </main:solidFill>
          </main:ln>
        </char:spPr>
        <char:cat>
          <char:strLit>
            <char:pt>
              <char:v>Val1</char:v>
            </char:pt>
            <char:pt>
              <char:v>Val2</char:v>
            </char:pt>
            <char:pt>
              <char:v>Val3</char:v>
            </char:pt>
          </char:strLit>
        </char:cat>
        <char:val>
          <char:numLit>
            <char:pt>
              <char:v>0.92</char:v>
            </char:pt>
          </char:numLit>
          <char:numLit>
            <char:pt>
              <char:v>0.95</char:v>
            </char:pt>
          </char:numLit>
          <char:numLit>
            <char:pt>
              <char:v>0.98</char:v>
            </char:pt>
          </char:numLit>
        </char:val>
      </char:ser>
      <char:axId val="123456"/>
      <char:axId val="123457"/>
    </char:barChart>
    <char:catAx>
      <char:axId val="123456"/>
      <char:scaling>
        <char:orientation val="minMax"/>
      </char:scaling>
      <char:delete val="false"/>
      <char:axPos val="b"/>
      <char:tickLblPos val="nextTo"/>
      <char:crossAx val="123457"/>
    </char:catAx>
    <char:valAx>
      <char:axId val="123457"/>
      <char:scaling>
        <char:orientation val="minMax"/>
      </char:scaling>
      <char:delete val="false"/>
      <char:axPos val="l"/>
      <char:tickLblPos val="nextTo"/>
      <char:crossAx val="123456"/>
    </char:valAx>
  </char:plotArea>
  <char:plotVisOnly val="true"/>
</xml-fragment>
Axel Richter

Main problems with your changings are:

  1. You forgot setting the Idx of the CTStrVal and the CTNumVal, you have added using addNewPt.

  2. CTNumData added to CTNumDataSource with addNewNumLit should contain as much CTNumVals like there are data points in the series. There should not be multiple CTNumDatain one series. With CTStrData in CTAxDataSource you have done it right - except the missing Idx, see 1.

Following code is creating the same chart as the one in the linked answer but without cell references:

import java.io.FileOutputStream;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.ss.usermodel.charts.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFChart;

import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarChart;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTBoolean;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTBarSer;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTAxDataSource;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumDataSource;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTSerTx;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTCatAx;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTScaling;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTLegend;
import org.openxmlformats.schemas.drawingml.x2006.chart.STAxPos;
import org.openxmlformats.schemas.drawingml.x2006.chart.STBarDir;
import org.openxmlformats.schemas.drawingml.x2006.chart.STOrientation;
import org.openxmlformats.schemas.drawingml.x2006.chart.STLegendPos;
import org.openxmlformats.schemas.drawingml.x2006.chart.STTickLblPos;

/*
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumRef;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrRef;
*/

import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrData;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumData;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTNumVal;
import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrVal;

public class BarChartPlainValues {

    public static void main(String[] args) throws Exception {
        Workbook wb = new XSSFWorkbook();
        Sheet sheet = wb.createSheet("Sheet1");

/*
cell filing code deleted
*/

        Drawing drawing = sheet.createDrawingPatriarch();
        ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 5, 8, 20);

        Chart chart = drawing.createChart(anchor);

        CTChart ctChart = ((XSSFChart)chart).getCTChart();
        CTPlotArea ctPlotArea = ctChart.getPlotArea();
        CTBarChart ctBarChart = ctPlotArea.addNewBarChart();
        CTBoolean ctBoolean = ctBarChart.addNewVaryColors();
        ctBoolean.setVal(true);
        ctBarChart.addNewBarDir().setVal(STBarDir.COL);

//new code start

        for (int s = 1; s < 5; s++) {
           CTBarSer ctBarSer = ctBarChart.addNewSer();
           CTSerTx ctSerTx = ctBarSer.addNewTx();
           ctSerTx.setV("Serie " + s);
           ctBarSer.addNewIdx().setVal(s-1);  

           CTAxDataSource ctAxDataSource = ctBarSer.addNewCat();
           CTStrData ctStrData = ctAxDataSource.addNewStrLit();
           ctStrData.addNewPtCount().setVal(3);
           CTStrVal ctStrVal = ctStrData.addNewPt();
           ctStrVal.setIdx(0);
           ctStrVal.setV("HEADER 1");
           ctStrVal = ctStrData.addNewPt();
           ctStrVal.setIdx(1);
           ctStrVal.setV("HEADER 2");
           ctStrVal = ctStrData.addNewPt();
           ctStrVal.setIdx(2);
           ctStrVal.setV("HEADER 3");

           CTNumDataSource ctNumDataSource = ctBarSer.addNewVal();
           CTNumData ctNumData = ctNumDataSource.addNewNumLit();
           ctNumData.addNewPtCount().setVal(3);
           CTNumVal ctNumVal = ctNumData.addNewPt();
           ctNumVal.setIdx(0);
           ctNumVal.setV("" + new java.util.Random().nextDouble());
           ctNumVal = ctNumData.addNewPt();
           ctNumVal.setIdx(1);
           ctNumVal.setV("" + new java.util.Random().nextDouble());
           ctNumVal = ctNumData.addNewPt();
           ctNumVal.setIdx(2);
           ctNumVal.setV("" + new java.util.Random().nextDouble());

           //at least the border lines in Libreoffice Calc ;-)
           ctBarSer.addNewSpPr().addNewLn().addNewSolidFill().addNewSrgbClr().setVal(new byte[] {0,0,0});   

        } 

//new code end

/*
chart reference code deleted
*/

        //telling the BarChart that it has axes and giving them Ids
        ctBarChart.addNewAxId().setVal(123456);
        ctBarChart.addNewAxId().setVal(123457);

        //cat axis
        CTCatAx ctCatAx = ctPlotArea.addNewCatAx(); 
        ctCatAx.addNewAxId().setVal(123456); //id of the cat axis
        CTScaling ctScaling = ctCatAx.addNewScaling();
        ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
        ctCatAx.addNewDelete().setVal(false);
        ctCatAx.addNewAxPos().setVal(STAxPos.B);
        ctCatAx.addNewCrossAx().setVal(123457); //id of the val axis
        ctCatAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);

        //val axis
        CTValAx ctValAx = ctPlotArea.addNewValAx(); 
        ctValAx.addNewAxId().setVal(123457); //id of the val axis
        ctScaling = ctValAx.addNewScaling();
        ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
        ctValAx.addNewDelete().setVal(false);
        ctValAx.addNewAxPos().setVal(STAxPos.L);
        ctValAx.addNewCrossAx().setVal(123456); //id of the cat axis
        ctValAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);

        //legend
        CTLegend ctLegend = ctChart.addNewLegend();
        ctLegend.addNewLegendPos().setVal(STLegendPos.B);
        ctLegend.addNewOverlay().setVal(false);

System.out.println(ctChart);

        FileOutputStream fileOut = new FileOutputStream("BarChartPlainValues.xlsx");
        wb.write(fileOut);
        fileOut.close();
    }
}

Problem: Normally arrays of string literals like ={"HEADER 1","HEADER 2","HEADER 3"} are not allowed as axis labels. Only references are allowed here. Excel accepts this while rendering the chart but you cannot edit those axis labels in Excel GUI.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Create Bar Chart in Excel with Apache POI

Apache poi - Bar Chart Set min and max values for left axis

dimple js values in bar chart outside chart

How to create pie & bar chart with Apache POI with XDDFDataSource values from custom List

Find Excel Cell by Text in Apache POI

Java apache poi: excel cell color

Reading a cell from Excel using Apache POI

line chart design in excel using Apache poi

Apache poi Excel line chart points

Create excel chart using Apache POI

Apache poi add label in excel chart

java apache poi bar chart populate negative bar with color

Formula Cell converting to Error Cell in excel using Apache POI

apache poi 4.0 bar chart example does not work

How to setup Apache POI Doughnut Chart Label outside of Chart using LeaderLine

How to read Excel cell having Date with Apache POI?

When does Apache POI framework consider a excel cell as empty and null?

Changing value of cell in Excel via apache-poi

Apache POI and Numeric Cell Types - Excel alerts of problem

Read merge cell in excel using Apache POI with Spring

Get Cell Value from Excel Sheet with Apache Poi

Pull Data Validation Out of an Excel Cell with Apache POI

How to Deal with empty or blank cell in excel file using apache poi

Java get the excel cell background color from Apache poi

Update Cell in excel file using Java Apache POI

Apache POI Focus on a particular cell in generated excel file

How to write in cell in excel using apache POI in JAVA?

Handle #REF! cell from excel using apache poi

how to read exact cell content of excel file in apache POI