2017-07-05 5 views
0

Ich versuche, ein Balkendiagramm in Excel-Datei mit Apache poi und dem folgenden Code zu erstellen: Create Bar Chart in Excel with Apache POI.Verwenden Sie Werte außerhalb Excel-Zelle in Apache Poi Balkendiagramm

In meinem Fall muss ich Datenwerte aus einer anderen Quelle anstelle der Excel-Zellen verwenden. Wie kann ich diese Werte im BarChart verwenden?

Angenommen, dass die Werte als ein Array von Float/Double-Werten kommen. Außerdem muss ich in der Lage sein, die Balkenfarben unabhängig einzustellen. Zum Beispiel sind einige Balken grün, während einige andere rot sind.

ich den Datenteil von Create Bar Chart in Excel with Apache POI Code in folgenden Weise geändert:

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

Jede Hilfe wird sehr geschätzt. Vielen Dank!

Wenn ich Ausgabe der Excel-Datei drucken, gibt es folgendes Ergebnis:

<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> 

Antwort

2

Haupt Probleme mit Ihrem changings sind:

  1. Sie haben vergessen, die Idx der CTStrVal Einstellung und die CTNumVal haben Sie mit addNewPt hinzugefügt.

  2. CTNumData hinzugefügt CTNumDataSource mit addNewNumLit sollte so viel CTNumVal s enthalten, wie es Datenpunkte in der Reihe sind. Es sollte nicht mehrere CTNumData in einer Serie sein. Mit CTStrData in CTAxDataSource Sie es richtig gemacht haben - mit Ausnahme der fehlenden Idx siehe 1.

folgenden Code ist das gleiche Diagramm wie das in der verknüpften Antwort zu schaffen, aber ohne Zellbezüge:

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: Normalerweise sind Arrays von String-Literalen wie ={"HEADER 1","HEADER 2","HEADER 3"} nicht als Achsenbeschriftungen zulässig. Nur Referenzen sind hier erlaubt. Excel akzeptiert dies beim Rendern des Diagramms, aber Sie können diese Achsenbeschriftungen nicht in Excel GUI bearbeiten.