How to set axis' labels in a Line Chart using Apache Poi
I'm trying to automate a report creation using java and Apache POI. I'm almost there, but can't find how to set the axis' labels in a XSSFChart.
I already found how to to set the chart's title( Apache POI set Excel chart title ). Maybe there is a similar way to work it around, but I'm no developer and have no idea on how to start.
Can anyone help?
My code up to now:
public void grafico(String nomeplanilhadados, String nomeplanilhagrafico, Date datainicial, Date datafinal, String[] nomesmarcos, String titulo){
if (datainicial.after(datafinal)){
throw new IllegalArgumentException("A data inicial precisa anteceder a data final");
}
Sheet dados = this.wb.getSheet(nomeplanilhadados);
Sheet planilhagrafico = this.wb.getSheet(nomeplanilhagrafico);
Drawing drawing = planilhagrafico.createDrawingPatriarch();
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 4, 17, 20);
Chart chart = drawing.createChart(anchor);
ChartLegend legend = chart.getOrCreateLegend();
legend.setPosition(LegendPosition.TOP_RIGHT);
LineChartData data = chart.getChartDataFactory().createLineChartData();
// Use a category axis for the bottom axis.
ChartAxis bottomAxis = chart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM);
bottomAxis.setNumberFormat("MMM/yyyy");
ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
//retrieve the data
int linhainicial=-1;
int linhafinal=-1;
Iterator<Row> rowIterator = dados.iterator();
while(rowIterator.hasNext()){
Row row = rowIterator.next();
Cell cell = row.getCell(0);
if(cell!=null){
SimpleDateFormat formatodata = new SimpleDateFormat("dd-MM-yyyy");
Date date=cell.getDateCellValue();
if (linhainicial==-1 && date.compareTo(datainicial)>=0){
linhainicial=cell.getRowIndex();
}
if( date.compareTo(datafinal)<=0){
linhafinal=cell.getRowIndex();
}
}
}
ChartDataSource<Number> xs = DataSources.fromNumericCellRange(dados, new CellRangeAddress(linhainicial, linhafinal, 0, 0));
Row primeiralinha = dados.getRow(0);
Iterator<Cell> cellIterator = primeiralinha.iterator();
while(cellIterator.hasNext()){
Cell cell=cellIterator.next();
if(cell!=null && Arrays.asList(nomesmarcos).contains(cell.getStringCellValue())){
ChartDataSource<Number> ys1 = DataSources.fromNumericCellRange(dados, new CellRangeAddress(linhainicial, linhafinal, cell.getColumnIndex(), cell.getColumnIndex()));
//data.addSerie(xs, ys1);
LineChartSerie chartSerie = data.addSerie(xs, ys1);
chartSerie.setTitle(cell.getStringCellValue());
}
}
XSSFChart xchart = (XSSFChart) chart;
CTChart ctChart = xchart.getCTChart();
CTTitle title = ctChart.addNewTitle();
CTTx tx = title.addNewTx();
CTTextBody rich = tx.addNewRich();
rich.addNewBodyPr(); // body properties must exist, but can be empty
CTTextParagraph para = rich.addNewP();
CTRegularTextRun r = para.addNewR();
r.setT(titulo);
chart.plot(data, bottomAxis, leftAxis);
}
Solution 1:
try use this method.
public static void setAxisTitle(XSSFChart chart, int axisIdx, String title) {
CTValAx valAx = chart.getCTChart().getPlotArea().getValAxArray(axisIdx);
CTTitle ctTitle = valAx.addNewTitle();
ctTitle.addNewLayout();
ctTitle.addNewOverlay().setVal(false);
CTTextBody rich = ctTitle.addNewTx().addNewRich();
rich.addNewBodyPr();
rich.addNewLstStyle();
CTTextParagraph p = rich.addNewP();
p.addNewPPr().addNewDefRPr();
p.addNewR().setT(title);
p.addNewEndParaRPr();
}