2016-08-08 5 views
1

Ich möchte von Java POI Zeile in Excel hinzuzufügen, und ich versuche, mit beiden shiftRows() Funktion und createRow() FunktionSo verschieben Position des Diagramms in Excel von Java POI

enter image description here
beide Funktion Zeile in Excel hinzufügen können aber unten ist Chartposition bewegen bleiben und nicht

ich mag auch die Position des Diagramms bewegen (herunterschalten)

I poi Version verwenden 3.9

Kann mir jemand den Rat oder die Idee geben, die Position dieses Diagrammbilds zu verschieben

Da die Tatsache, der Datenbereich des Diagramms auch nicht geändert. Ich muss nicht nur die Position von Diagrammen verschieben, sondern muss auch den Datenbereich des Diagramms erhöhen

danke !!

enter image description here

+0

Wirklich nur die Positionen der Charts verschieben? Das wird einfach sein. Aber wie Sie sehen, ist das Diagramm auch wegen des Einfügens einer Zeile in den Quelldatenbereich des Diagramms unterbrochen. –

+0

Danke für Ihren Hinweis. Ja, der Datenbereich des Diagramms wurde ebenfalls nicht geändert. Ich muss nicht nur die Position von Diagrammen verschieben, sondern auch den Datenbereich des Diagramms vergrößern. – AKZap

+0

Das Ändern des Datenbereichs des Diagramms wird kompliziert. Vor allem, wenn dies für alle Diagrammtypen erforderlich ist. Wenn auch nur für Tortendiagramme, dann ist das Problem, dass Apache Poi standardmäßig keine Tortendiagramme unterstützt. Es werden nur Liniendiagramme und Streudiagramme unterstützt. Aber wir könnten die zugrunde liegenden Objekte verwenden. Ich werde heute Abend ein Beispiel für Tortendiagramme geben (Mitteleuropäische Zeit). –

Antwort

4

Die Verschiebung der Zieh Anker, die die Diagrammpositionen bestimmen, möglich ist. Die Methode void insertRowsShiftShapes(Sheet sheet, int startRow, int n) führt dies für alle Zeichenanker aus, die vom Zeileneinfügevorgang betroffen sind.

Die Korrektur der Diagrammdatenbereiche, die von der Zeileneinfügung in das Blatt betroffen sind, ist wie bereits gesagt kompliziert. Es ist nicht gut getestet und noch nicht fertig. Aber ich werde es als Arbeitsentwurf zur Verfügung stellen. Ich hoffe, es ist ein nützlicher Ausgangspunkt für die weitere Programmierung.

Für den Code läuft die ooxml-schemas-1.3.jar benötigt wird, als für mich in apache poi FAQ

eine gute Ressource für die Dokumentation der OOXML-Schemaobjekte erwähnt ist grepcode

Beispiele: 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) { 
    } 
} 
} 
+0

Vielen Dank !!! Es ist wirklich nützlich und macht mir Sinn für die weitere Programmierung – AKZap

+0

Gibt es einen möglichen Weg für HSSF-Typ für Ihre Lösung? Es funktioniert gut mit XSSF-Typ, aber meine Ziel-Eingabedatei ist * .xls Dateityp – AKZap

+0

@AKZap: Sorry, aber ich werde mich nicht mit den alten Binär-Formaten von Microsoft Office kümmern. Ihre Formate sind schmerzhaft und seit 2007 veraltet.Bei den XML-Formaten besteht die Möglichkeit, Informationen aus dem XML zu erhalten, das von den Office-Anwendungen generiert wird. Die binären Formate sind schmerzhaft kryptisch. –