如何通过Java POI在Excel中移动图表的位置

我想通过java POI在Excel中添加行,我尝试使用shiftRows()函数和createRow()函数

在这里输入图像说明
两个函数都可以在excel中添加行但下图位置保持不动

我也喜欢移动(下移)图表的位置

我使用poi版本3.9

任何人都可以给我build议或想法来移动图表图像的位置

事实上,图表的数据范围也没有改变。 我不仅需要移动图表的位置,还需要增加图表的数据范围

谢谢!!

在这里输入图像说明

确定图表位置的绘图锚的移动是可能的。 方法void insertRowsShiftShapes(Sheet sheet, int startRow, int n)为所有影响行插入过程的graphics锚点执行此操作。

如上所述,影响插入到纸张中的行的图表数据范围的校正是复杂的。 它没有很好的testing,还没有准备好。 但我会把它作为一个工作草案。 我希望这是进一步编程的一个有用的起点。

为了运行代码,需要在apache poi FAQ中提到的ooxml-schemas-1.3.jar

grepcode是我为ooxml -schema对象创build文档的一个很好的资源

示例: CTTwoCellAnchor , CTPieChart , CTPieSer

 import org.apache.poi.xssf.usermodel.*; import org.apache.poi.ss.usermodel.*; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import java.io.*; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor; import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieChart; import org.openxmlformats.schemas.drawingml.x2006.chart.CTPieSer; import java.util.List; class InsertRowsAboveChart { //a method for shift rows and shift all anchors in drawing below the shifted rows private static void insertRowsShiftShapes(Sheet sheet, int startRow, int n) { java.util.List<CTTwoCellAnchor> drawingAnchors = ((XSSFDrawing)sheet.getDrawingPatriarch()).getCTDrawing().getTwoCellAnchorList(); for (CTTwoCellAnchor drawingAnchor : drawingAnchors) { int fromRow = drawingAnchor.getFrom().getRow(); int toRow = drawingAnchor.getTo().getRow(); if (fromRow >= startRow) { drawingAnchor.getFrom().setRow(fromRow + n); drawingAnchor.getTo().setRow(toRow + n); } } sheet.shiftRows(startRow, sheet.getLastRowNum(), n); correctDataRangesOfCharts(sheet, startRow, n); } //a method for correcting data ranges for charts which are affected of the shifted rows //!!working draft, not ready yet!! private static void correctDataRangesOfCharts(Sheet sheet, int startRow, int n) { java.util.List<XSSFChart> charts = ((XSSFDrawing)sheet.getDrawingPatriarch()).getCharts(); for (XSSFChart chart : charts) { //pie charts java.util.List<CTPieChart> piecharts = chart.getCTChart().getPlotArea().getPieChartList(); for (CTPieChart piechart : piecharts) { java.util.List<CTPieSer> pieseries = piechart.getSerList(); for (CTPieSer pieserie : pieseries) { boolean strRefchanged = false; if (pieserie.getCat().isSetMultiLvlStrRef()) { String strRef = pieserie.getCat().getMultiLvlStrRef().getF(); //todo: this only corrects the end row of the ranges, should also correct start row if affected int strRefEndRow = Integer.parseInt(strRef.substring(strRef.lastIndexOf('$') + 1)); if (strRefEndRow >= startRow) { strRef = strRef.substring(0, strRef.lastIndexOf('$') +1) + (strRefEndRow + n); pieserie.getCat().getMultiLvlStrRef().setF(strRef); strRefchanged = true; } } else if (pieserie.getCat().isSetStrRef()) { String strRef = pieserie.getCat().getStrRef().getF(); int strRefEndRow = Integer.parseInt(strRef.substring(strRef.lastIndexOf('$') + 1)); if (strRefEndRow >= startRow) { strRef = strRef.substring(0, strRef.lastIndexOf('$') +1) + (strRefEndRow + n); pieserie.getCat().getStrRef().setF(strRef); strRefchanged = true; } } if (strRefchanged) { String numRef = pieserie.getVal().getNumRef().getF(); int numRefEndRow = Integer.parseInt(numRef.substring(numRef.lastIndexOf('$') + 1)); if (numRefEndRow >= startRow) { numRef = numRef.substring(0, numRef.lastIndexOf('$') +1) + (numRefEndRow + n); pieserie.getVal().getNumRef().setF(numRef); } } } } //pie charts end } } public static void main(String[] args) { try { InputStream inp = new FileInputStream("Workbook.xlsx"); Workbook wb = WorkbookFactory.create(inp); Sheet sheet = wb.getSheetAt(0); //sheet.shiftRows(3, 5, 4); insertRowsShiftShapes(sheet, 2, 4); FileOutputStream fileOut = new FileOutputStream("Workbook.xlsx"); wb.write(fileOut); wb.close(); } catch (InvalidFormatException ifex) { } catch (FileNotFoundException fnfex) { } catch (IOException ioex) { } } }