簡體   English   中英

使用openxmlformats在條形圖中創建目標標記

[英]Create target marker in a bar chart with openxmlformats

使用apache POI和openxmlformats,我用條形圖構建了一個excel。 我做條形圖的方式是:

private static CTChart createBarChart(Chart chart, String dataSheet, ArrayList<Integer> cols, int lastRow, boolean seriesInCols) {
        CTChart ctChart = ((XSSFChart) chart).getCTChart();
        CTPlotArea ctPlotArea = ctChart.getPlotArea();
        CTBarChart ctBarChart = ctPlotArea.addNewBarChart();
        CTBoolean ctBoolean = ctBarChart.addNewVaryColors();
        ctBoolean.setVal(true);
        ctBarChart.addNewBarDir().setVal(cols.size() > 1 ? STBarDir.COL : STBarDir.BAR);

        int idx = 0;

        for (Integer c : cols) {
            CTBarSer ctBarSer = ctBarChart.addNewSer();
            CTSerTx ctSerTx = ctBarSer.addNewTx();
            CTStrRef ctStrRef = ctSerTx.addNewStrRef();
            ctStrRef.setF(new CellReference(dataSheet, 0, c, true, true).formatAsString());

            ctBarSer.addNewIdx().setVal(idx++);
            CTAxDataSource cttAxDataSource = ctBarSer.addNewCat();
            ctStrRef = cttAxDataSource.addNewStrRef();

            ctStrRef.setF(new AreaReference(new CellReference(dataSheet, 1, 0, true, true), new CellReference(dataSheet, lastRow, 0, true, true), SpreadsheetVersion.EXCEL2007)
                    .formatAsString());

            CTNumDataSource ctNumDataSource = ctBarSer.addNewVal();
            CTNumRef ctNumRef = ctNumDataSource.addNewNumRef();

            ctNumRef.setF(new AreaReference(new CellReference(dataSheet, 1, c, true, true), new CellReference(dataSheet, lastRow, c, true, true), SpreadsheetVersion.EXCEL2007)
                    .formatAsString());

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

        }

        // 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
        if (cols.size() > 1) {
            CTLegend ctLegend = ctChart.addNewLegend();
            ctLegend.addNewLegendPos().setVal(STLegendPos.L);
            ctLegend.addNewOverlay().setVal(false);
        }
        return ctChart;

    }

這種方法是我生成圖表的方式。 結果是 在此處輸入圖片說明

但是現在我需要像這樣在圖表中放置目標線

在此處輸入圖片說明

但是我不知道怎么做,也沒有找到任何信息。

謝謝

這里的第一個問題是,您將如何使用Excel的GUI進行此操作?

一種方法是添加一個散點圖系列,該散點圖系列具有兩個數據點X / Y(分別為0 / TARGET和1 / TARGET)並與一條直線鏈接,並且具有單獨的軸。 在單獨的X軸中,最小值為0,最大值為1。這取決於Y軸是垂直還是水平,導致Y = TARGET上出現垂直或水平線。

我已經將您的代碼放入完整的示例中,並為此方法添加了代碼。

啟動Excel工作表是:

在此處輸入圖片說明

碼:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.xssf.usermodel.XSSFChart;
import org.apache.poi.ss.SpreadsheetVersion;

import org.openxmlformats.schemas.drawingml.x2006.chart.*;

import java.io.FileInputStream;
import java.io.FileOutputStream;

import java.util.ArrayList;

class ExcelCharWithTargetLine {

 private static CTChart createBarChart(XSSFChart chart, String dataSheet, ArrayList<Integer> cols, int lastRow, double target) {

  CTChart ctChart = chart.getCTChart();
  CTPlotArea ctPlotArea = ctChart.getPlotArea();
  CTBarChart ctBarChart = ctPlotArea.addNewBarChart();
  CTBoolean ctBoolean = ctBarChart.addNewVaryColors();
  ctBoolean.setVal(true);
  ctBarChart.addNewBarDir().setVal(cols.size() > 1 ? STBarDir.COL : STBarDir.BAR);

  int idx = 0;

  for (Integer c : cols) {
   CTBarSer ctBarSer = ctBarChart.addNewSer();
   CTSerTx ctSerTx = ctBarSer.addNewTx();
   CTStrRef ctStrRef = ctSerTx.addNewStrRef();
   ctStrRef.setF(new CellReference(dataSheet, 0, c, true, true).formatAsString());

   ctBarSer.addNewIdx().setVal(idx++);
   CTAxDataSource cttAxDataSource = ctBarSer.addNewCat();
   ctStrRef = cttAxDataSource.addNewStrRef();

   ctStrRef.setF(new AreaReference(
                  new CellReference(dataSheet, 1, 0, true, true), 
                  new CellReference(dataSheet, lastRow, 0, true, true), 
                  SpreadsheetVersion.EXCEL2007).formatAsString()
                 );

   CTNumDataSource ctNumDataSource = ctBarSer.addNewVal();
   CTNumRef ctNumRef = ctNumDataSource.addNewNumRef();

   ctNumRef.setF(new AreaReference(
                  new CellReference(dataSheet, 1, c, true, true), 
                  new CellReference(dataSheet, lastRow, c, true, true), 
                  SpreadsheetVersion.EXCEL2007).formatAsString()
                 );

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

  }

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


  // target line
  // line of a scatter chart from 0 (min) to 1 (max) having value of double target
  CTScatterChart ctScatterChart = ctPlotArea.addNewScatterChart();
  ctBoolean = ctScatterChart.addNewVaryColors();
  ctBoolean.setVal(true);

  CTScatterSer ctScatterSer = ctScatterChart.addNewSer();
  ctScatterSer.addNewIdx().setVal(idx++);
  ctScatterSer.addNewMarker().addNewSymbol().setVal(STMarkerStyle.NONE);

  CTNumData ctNumData = ctScatterSer.addNewXVal().addNewNumLit();
  ctNumData.addNewPtCount().setVal(2);
  CTNumVal ctNumVal = ctNumData.addNewPt();
  ctNumVal.setIdx(0);

  if (cols.size() > 1) {
   ctNumVal.setV("0"); // if STBarDir.COL then X axis is from 0 to 1
  } else {
   ctNumVal.setV("" + target); // if STBarDir.BAR then X axis is value axis
  }

  ctNumVal = ctNumData.addNewPt();
  ctNumVal.setIdx(1);

  if (cols.size() > 1) {
   ctNumVal.setV("1");
  } else {
   ctNumVal.setV("" + target);
  }

  ctNumData = ctScatterSer.addNewYVal().addNewNumLit();
  ctNumData.addNewPtCount().setVal(2);
  ctNumVal = ctNumData.addNewPt();
  ctNumVal.setIdx(0);

  if (cols.size() > 1) {
   ctNumVal.setV("" + target); // if STBarDir.COL then Y axis is value axis
  } else {
   ctNumVal.setV("0"); // if STBarDir.BAR then Y axis is from 0 to 1
  }

  ctNumVal = ctNumData.addNewPt();
  ctNumVal.setIdx(1);

  if (cols.size() > 1) {
   ctNumVal.setV("" + target);
  } else {
   ctNumVal.setV("1");
  }

  ctScatterChart.addNewAxId().setVal(123458);
  ctScatterChart.addNewAxId().setVal(123459);

  ctValAx = ctPlotArea.addNewValAx();
  ctValAx.addNewAxId().setVal(123458); // id of the X axis
  ctScaling = ctValAx.addNewScaling();
  ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
  if (cols.size() > 1) {
   ctScaling.addNewMax().setVal(1.0);
  }
  ctValAx.addNewDelete().setVal(true);
  ctValAx.addNewAxPos().setVal(STAxPos.T);
  ctValAx.addNewCrossAx().setVal(123459); // id of the Y axis
  ctValAx.addNewTickLblPos().setVal(STTickLblPos.NONE);

  ctValAx = ctPlotArea.addNewValAx();
  ctValAx.addNewAxId().setVal(123459); // id of the Y axis
  ctScaling = ctValAx.addNewScaling();
  ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
  if (cols.size() == 1) {
   ctScaling.addNewMax().setVal(1.0);
  }
  ctValAx.addNewDelete().setVal(true);
  ctValAx.addNewAxPos().setVal(STAxPos.R);
  ctValAx.addNewCrossAx().setVal(123458); // id of the X axis
  ctValAx.addNewTickLblPos().setVal(STTickLblPos.NONE);


  // legend
  if (cols.size() > 1) {
   CTLegend ctLegend = ctChart.addNewLegend();
   ctLegend.addNewLegendPos().setVal(STLegendPos.L);

   // delete additional target line series legent entry
   CTLegendEntry ctLegendEntry = ctLegend.addNewLegendEntry();
   ctLegendEntry.addNewIdx().setVal(0);
   ctLegendEntry.addNewDelete().setVal(true);

   ctLegend.addNewOverlay().setVal(false);
  }

  return ctChart;

 }

 public static void main(String[] args) throws Exception {

  Workbook workbook = WorkbookFactory.create(new FileInputStream("ExcelChart.xlsx"));

  Sheet sheet = workbook.getSheetAt(0);

  ArrayList<Integer> cols = new ArrayList<Integer>();
  //cols.add(1);
  cols.add(2);
  //cols.add(3);

  Drawing drawing = sheet.createDrawingPatriarch();
  ClientAnchor anchor = null;
  if (cols.size() > 1) {
   anchor = drawing.createAnchor(0, 0, 0, 0, 0, 8, 10, 23);
  } else {
   anchor = drawing.createAnchor(0, 0, 0, 0, 0, 8, 5, 23);
  }
  Chart chart = drawing.createChart(anchor);
  CTChart ctChart = ctChart = createBarChart((XSSFChart) chart, sheet.getSheetName(), cols, 6, 42.0);

  workbook.write(new FileOutputStream("ExcelChartNew.xlsx"));
  workbook.close();

 }
}

結果:

在此處輸入圖片說明

筆記:

此示例需要FAQ-N10025中提到的所有模式ooxml-schemas-1.3.jar的完整jar。

這僅適用於Excel,因為OpenOffice或Libreoffice Calc無法設置具有文字數值的系列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM