Skip to content
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 93 additions & 17 deletions poi-ooxml/src/main/java/org/apache/poi/xwpf/usermodel/XWPFChart.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,27 @@ Licensed to the Apache Software Foundation (ASF) under one or more

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.ooxml.POIXMLFactory;
import org.apache.poi.ooxml.POIXMLRelation;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellAddress;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.Beta;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xddf.usermodel.chart.XDDFChart;
import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;

Expand Down Expand Up @@ -58,7 +70,7 @@ public class XWPFChart extends XDDFChart {
* constructor to
* Create a new chart in document
*
* @since 4.0.0
* @since POI 4.0.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't change these values

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes sorry I didnt intend to but Im struggling with GIT, if you could revert it that would help

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what can I revert in your PR?

Copy link
Contributor Author

@emmanueldufour emmanueldufour Dec 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since 4.0.0 vs since POI 4.0.0

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't offering to do it. I was asking why I'm expected to do it.

*/
protected XWPFChart() {
super();
Expand All @@ -69,7 +81,7 @@ protected XWPFChart() {
*
* @param part the package part holding the chart data,
* the content type must be {@code application/vnd.openxmlformats-officedocument.drawingml.chart+xml}
* @since 4.0.0
* @since POI 4.0.0
*/
protected XWPFChart(PackagePart part) throws IOException, XmlException {
super(part);
Expand Down Expand Up @@ -116,7 +128,7 @@ public int hashCode() {
*
* @param chartRelId the relation id of this chart in its parent document.
* @param run the text run to which this chart will be inlined.
* @since 4.0.0
* @since POI 4.0.0
*/
protected void attach(String chartRelId, XWPFRun run)
throws InvalidFormatException, IOException {
Expand All @@ -129,7 +141,7 @@ protected void attach(String chartRelId, XWPFRun run)
* set chart height
*
* @param height height of chart
* @since 4.0.0
* @since POI 4.0.0
*/
public void setChartHeight(long height) {
ctInline.getExtent().setCy(height);
Expand All @@ -139,7 +151,7 @@ public void setChartHeight(long height) {
* set chart width
*
* @param width width of chart
* @since 4.0.0
* @since POI 4.0.0
*/
public void setChartWidth(long width) {
ctInline.getExtent().setCx(width);
Expand All @@ -148,7 +160,7 @@ public void setChartWidth(long width) {
/**
* get chart height
*
* @since 4.0.0
* @since POI 4.0.0
*/
public long getChartHeight() {
return ctInline.getExtent().getCy();
Expand All @@ -157,7 +169,7 @@ public long getChartHeight() {
/**
* get chart width
*
* @since 4.0.0
* @since POI 4.0.0
*/
public long getChartWidth() {
return ctInline.getExtent().getCx();
Expand All @@ -168,7 +180,7 @@ public long getChartWidth() {
*
* @param width width of chart
* @param height height of chart
* @since 4.0.0
* @since POI 4.0.0
*/
public void setChartBoundingBox(long width, long height) {
this.setChartWidth(width);
Expand All @@ -179,7 +191,7 @@ public void setChartBoundingBox(long width, long height) {
* set margin from top
*
* @param margin margin from top
* @since 4.0.0
* @since POI 4.0.0
*/
public void setChartTopMargin(long margin) {
ctInline.setDistT(margin);
Expand All @@ -188,7 +200,7 @@ public void setChartTopMargin(long margin) {
/**
* get margin from Top
*
* @since 4.0.0
* @since POI 4.0.0
*/
public long getChartTopMargin(long margin) {
return ctInline.getDistT();
Expand All @@ -198,7 +210,7 @@ public long getChartTopMargin(long margin) {
* set margin from bottom
*
* @param margin margin from Bottom
* @since 4.0.0
* @since POI 4.0.0
*/
public void setChartBottomMargin(long margin) {
ctInline.setDistB(margin);
Expand All @@ -207,7 +219,7 @@ public void setChartBottomMargin(long margin) {
/**
* get margin from Bottom
*
* @since 4.0.0
* @since POI 4.0.0
*/
public long getChartBottomMargin(long margin) {
return ctInline.getDistB();
Expand All @@ -217,7 +229,7 @@ public long getChartBottomMargin(long margin) {
* set margin from left
*
* @param margin margin from left
* @since 4.0.0
* @since POI 4.0.0
*/
public void setChartLeftMargin(long margin) {
ctInline.setDistL(margin);
Expand All @@ -226,7 +238,7 @@ public void setChartLeftMargin(long margin) {
/**
* get margin from left
*
* @since 4.0.0
* @since POI 4.0.0
*/
public long getChartLeftMargin(long margin) {
return ctInline.getDistL();
Expand All @@ -236,7 +248,7 @@ public long getChartLeftMargin(long margin) {
* set margin from Right
*
* @param margin from right
* @since 4.0.0
* @since POI 4.0.0
*/
public void setChartRightMargin(long margin) {
ctInline.setDistR(margin);
Expand All @@ -245,7 +257,7 @@ public void setChartRightMargin(long margin) {
/**
* get margin from Right
*
* @since 4.0.0
* @since POI 4.0.0
*/
public long getChartRightMargin(long margin) {
return ctInline.getDistR();
Expand All @@ -258,12 +270,76 @@ public long getChartRightMargin(long margin) {
* @param right margin from right
* @param bottom margin from bottom
* @param left margin from left
* @since 4.0.0
* @since POI 4.0.0
*/
public void setChartMargin(long top, long right, long bottom, long left) {
this.setChartBottomMargin(bottom);
this.setChartRightMargin(right);
this.setChartLeftMargin(left);
this.setChartRightMargin(right);
}
/**
* Word keeps cached values that need be refreshed after the embedded workbook
* has been updated. This is just the first step refreshing categories and
* series labels (tested for bar charts). TODO ultimately a function should be
* provided to refresh the entire cache
*/
public void refreshCachedLabels() {
Workbook wb;
try {
wb = getWorkbook();
} catch (InvalidFormatException | IOException e) {
return;
}
for (XDDFChartData chartData : getChartSeries()) {
for (int chartIndex = 0; chartIndex < chartData.getSeriesCount(); chartIndex++) {
XDDFChartData.Series series = chartData.getSeries(chartIndex);
String freshSeriesTitle=getWorkbookCellValue( series.getTitleReference(),wb);
series.setTitleCached(freshSeriesTitle);
XDDFDataSource<?> catData = series.getCategoryData();
if (catData == null)
continue;
String referenceFormula = catData.getFormula();
if (referenceFormula != null) {
List<Cell> cells = getWorkbookCells(referenceFormula, wb);
String[] freshCategories = new String[cells.size()];
int categIndex = 0;
for (Cell cell : cells) {
freshCategories[categIndex++] = cell.toString();
}
// create categories from a range formula and the values below, it will create then as "cached" values like word expects
XDDFDataSource<String> freshCategoryDataSrouce = XDDFDataSourcesFactory.fromArray(freshCategories,referenceFormula);
series.replaceData(freshCategoryDataSrouce, (XDDFNumericalDataSource<?>) series.getValuesData());
}
}
//this mystery "plot" will somehow update the underlying document XML
plot(chartData);
}
}
/**
*
* @param cell must include the sheet reference
* @param wb
* @return toString() value of the cell
*/
private static String getWorkbookCellValue(CellReference cell, Workbook wb) {

return wb.getSheet( cell.getSheetName()).getRow(cell.getRow()).getCell(cell.getCol()).toString();

}
/**
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whitespace between methods - no need for all the whitespace inside the method - please try to make the code follow the existing style in classes

*
* @param rangeFormula for example: "Sheet1!$A$2:$A$5"
* @return
*/
private static List<Cell> getWorkbookCells(String rangeFormula, Workbook wb) {
List<Cell> cells = new ArrayList<Cell>();
String[] parts = rangeFormula.split("!");// get formula gives the ref like: Sheet1!$A$2:$A$5
Sheet sheet = wb.getSheet(parts[0]);
CellRangeAddress range = CellRangeAddress.valueOf(parts[1]);
for (CellAddress cellAddress : range) {// the iterator goes top to bottom, left to right
cells.add(sheet.getRow(cellAddress.getRow()).getCell(cellAddress.getColumn()));
}
return cells;
}
}