You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@poi.apache.org by Alain FAGOT BÉAREZ <AB...@FOR-Scala.IT> on 2018/09/03 23:27:06 UTC

Re: Copying chart

Hi FD,

I think all you need is the following method on XSSFDrawing:

```
    /**
     * Imports the chart from the <code>srcChart</code> into this drawing.
     *
     * @param srcChart
     *            the source chart to be cloned into this drawing.
     * @return the newly created chart.
     * @throws XmlException
     * @throws IOException
     */
    public XSSFChart importChart(XSSFChart srcChart) throws IOException, XmlException {
        CTTwoCellAnchor anchor = ((XSSFDrawing) srcChart.getParent()).getCTDrawing().getTwoCellAnchorArray(0);
        CTMarker from = (CTMarker) anchor.getFrom().copy();
        CTMarker to = (CTMarker) anchor.getTo().copy();
        XSSFClientAnchor destAnchor = new XSSFClientAnchor(from, to);
        destAnchor.setAnchorType(AnchorType.MOVE_AND_RESIZE);
        XSSFChart destChart = createChart(destAnchor);
        destChart.getCTChartSpace().set(srcChart.getCTChartSpace().copy());
        destChart.getCTChart().set(srcChart.getCTChart().copy());
        return destChart;
    }
```

I feel that retrieving the source chart and creating the new destination drawing are better handled outside.

I will open a PR for code review.

Best regards,
Alain


> On 24 Aug 2018, at 10:50, monnomiznogoud@gmail.com wrote:
> 
> Hi Alain,
> 
> I'll paste some test code here. In my work we have a lot of restrictions when it comes to websites.
> 
> Sorry I don't know how to format this code.
> 
> Important: the chartModel.xlsx should contain a chart, preferably with no relations. After all you need the model to be copied to your report but then you must at least implement the data source for the chart, maybe also the title, the series names, etc. But the heavy customization of the chart is already done in the model.
> 
>    //Open chart model file
> 	//My use experience: one chart par xlsx model file, in one sheet. Could be otherwise of course.
> 	FileInputStream in = new FileInputStream("c:/temp/chartModel.xlsx");
>    XSSFWorkbook srcWB = new XSSFWorkbook(in);
>    XSSFWorkbook destWB = new XSSFWorkbook();
>    XSSFSheet destSH = destWB.createSheet();
>    XSSFDrawing destDR = destSH.createDrawingPatriarch();
>    int sheetNum = 0; 
>    XSSFSheet srcSH = srcWB.getSheetAt(sheetNum);
> 
>    List<POIXMLDocumentPart> srcRels = srcSH.createDrawingPatriarch().getRelations();
>    for (POIXMLDocumentPart srcRel : srcRels)
>    {
>      if (srcRel instanceof XSSFChart)
>      {
>        XSSFChart srcChart = (XSSFChart) srcRel;
> 		
> 		//Create chartSpace and chart by parsing source chart
> 	    CTChartSpace chartSpace = ChartSpaceDocument.Factory.parse(srcChart.getPackagePart().getInputStream(), POIXMLTypeLoader.DEFAULT_XML_OPTIONS).getChartSpace(); 
> 	    CTChart ctc = chartSpace.getChart();
> 
>        //XSSFClientAnchor origAnch = chart.getGraphicFrame().getAnchor();
> 		//Frame is null ! I tried to get anchor using the following:
>        CTMarker from = ((XSSFDrawing) srcChart.getParent()).getCTDrawing().getTwoCellAnchorArray(0).getFrom();
>        CTMarker to = ((XSSFDrawing) srcChart.getParent()).getCTDrawing().getTwoCellAnchorArray(0).getTo();
>        XSSFClientAnchor anchor = new XSSFClientAnchor((int) from.getColOff(), (int) from.getRowOff(), (int) to.getColOff(), (int) to.getRowOff(), from.getCol(), from.getRow(), to.getCol(), to.getRow());
>        anchor.setAnchorType(AnchorType.MOVE_AND_RESIZE);
>       //Create chart in the destination workbook
>        XSSFChart destChart = destDR.createChart(anchor);
> 		
> 		//A new XSSFChart constructor is needed maybe. The following 2 lines use reflection in order to force values for these 2 private variables of XSSFChart
>        Utilities.setVariable(destChart, "chartSpace", chartSpace, true);
>        Utilities.setVariable(destChart, "chart", ctc, true);
> 	  }
> 	}
> 	
> 	//Write the new workbook (could also be one you already have opened for edition)
>    FileOutputStream out = new FileOutputStream("c:/temp/test.xlsx");
>    destWB.write(out);
>    out.flush();
>    out.close();
>    in.close();
>    srcWB.close();
>    destWB.close();
> 		
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@poi.apache.org
> For additional commands, e-mail: dev-help@poi.apache.org


Re: Copying chart

Posted by Alain FAGOT BÉAREZ <AB...@FOR-Scala.IT>.
Hi FD,

The code has been merged by r1840076. It might appear in release 4.0.0 or 4.0.1 (we are currently busy with 4.0.0 RC1).

Best regards,
Alain

> On 4 Sep 2018, at 00:27, Alain FAGOT BÉAREZ <AB...@FOR-Scala.IT> wrote:
> 
> Hi FD,
> 
> I think all you need is the following method on XSSFDrawing:
> 
> ```
>    /**
>     * Imports the chart from the <code>srcChart</code> into this drawing.
>     *
>     * @param srcChart
>     *            the source chart to be cloned into this drawing.
>     * @return the newly created chart.
>     * @throws XmlException
>     * @throws IOException
>     */
>    public XSSFChart importChart(XSSFChart srcChart) throws IOException, XmlException {
>        CTTwoCellAnchor anchor = ((XSSFDrawing) srcChart.getParent()).getCTDrawing().getTwoCellAnchorArray(0);
>        CTMarker from = (CTMarker) anchor.getFrom().copy();
>        CTMarker to = (CTMarker) anchor.getTo().copy();
>        XSSFClientAnchor destAnchor = new XSSFClientAnchor(from, to);
>        destAnchor.setAnchorType(AnchorType.MOVE_AND_RESIZE);
>        XSSFChart destChart = createChart(destAnchor);
>        destChart.getCTChartSpace().set(srcChart.getCTChartSpace().copy());
>        destChart.getCTChart().set(srcChart.getCTChart().copy());
>        return destChart;
>    }
> ```
> 
> I feel that retrieving the source chart and creating the new destination drawing are better handled outside.
> 
> I will open a PR for code review.
> 
> Best regards,
> Alain
> 
> 
>> On 24 Aug 2018, at 10:50, monnomiznogoud@gmail.com wrote:
>> 
>> Hi Alain,
>> 
>> I'll paste some test code here. In my work we have a lot of restrictions when it comes to websites.
>> 
>> Sorry I don't know how to format this code.
>> 
>> Important: the chartModel.xlsx should contain a chart, preferably with no relations. After all you need the model to be copied to your report but then you must at least implement the data source for the chart, maybe also the title, the series names, etc. But the heavy customization of the chart is already done in the model.
>> 
>>   //Open chart model file
>> 	//My use experience: one chart par xlsx model file, in one sheet. Could be otherwise of course.
>> 	FileInputStream in = new FileInputStream("c:/temp/chartModel.xlsx");
>>   XSSFWorkbook srcWB = new XSSFWorkbook(in);
>>   XSSFWorkbook destWB = new XSSFWorkbook();
>>   XSSFSheet destSH = destWB.createSheet();
>>   XSSFDrawing destDR = destSH.createDrawingPatriarch();
>>   int sheetNum = 0; 
>>   XSSFSheet srcSH = srcWB.getSheetAt(sheetNum);
>> 
>>   List<POIXMLDocumentPart> srcRels = srcSH.createDrawingPatriarch().getRelations();
>>   for (POIXMLDocumentPart srcRel : srcRels)
>>   {
>>     if (srcRel instanceof XSSFChart)
>>     {
>>       XSSFChart srcChart = (XSSFChart) srcRel;
>> 		
>> 		//Create chartSpace and chart by parsing source chart
>> 	    CTChartSpace chartSpace = ChartSpaceDocument.Factory.parse(srcChart.getPackagePart().getInputStream(), POIXMLTypeLoader.DEFAULT_XML_OPTIONS).getChartSpace(); 
>> 	    CTChart ctc = chartSpace.getChart();
>> 
>>       //XSSFClientAnchor origAnch = chart.getGraphicFrame().getAnchor();
>> 		//Frame is null ! I tried to get anchor using the following:
>>       CTMarker from = ((XSSFDrawing) srcChart.getParent()).getCTDrawing().getTwoCellAnchorArray(0).getFrom();
>>       CTMarker to = ((XSSFDrawing) srcChart.getParent()).getCTDrawing().getTwoCellAnchorArray(0).getTo();
>>       XSSFClientAnchor anchor = new XSSFClientAnchor((int) from.getColOff(), (int) from.getRowOff(), (int) to.getColOff(), (int) to.getRowOff(), from.getCol(), from.getRow(), to.getCol(), to.getRow());
>>       anchor.setAnchorType(AnchorType.MOVE_AND_RESIZE);
>>      //Create chart in the destination workbook
>>       XSSFChart destChart = destDR.createChart(anchor);
>> 		
>> 		//A new XSSFChart constructor is needed maybe. The following 2 lines use reflection in order to force values for these 2 private variables of XSSFChart
>>       Utilities.setVariable(destChart, "chartSpace", chartSpace, true);
>>       Utilities.setVariable(destChart, "chart", ctc, true);
>> 	  }
>> 	}
>> 	
>> 	//Write the new workbook (could also be one you already have opened for edition)
>>   FileOutputStream out = new FileOutputStream("c:/temp/test.xlsx");
>>   destWB.write(out);
>>   out.flush();
>>   out.close();
>>   in.close();
>>   srcWB.close();
>>   destWB.close();
>> 		
>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@poi.apache.org
>> For additional commands, e-mail: dev-help@poi.apache.org
>