Java 使用ApachePOI更新瀑布图
我正在使用ApachePOIJava库(v4.1.1)创建wonderfull Word文档,包括Excel图表。对于Excel图表,我使用Excel模板,并通过ApachePOI库访问Word文档中的图表Java 使用ApachePOI更新瀑布图,java,excel,apache-poi,Java,Excel,Apache Poi,我正在使用ApachePOIJava库(v4.1.1)创建wonderfull Word文档,包括Excel图表。对于Excel图表,我使用Excel模板,并通过ApachePOI库访问Word文档中的图表 List<XWPFChart> chartList = wordDoc.getCharts(); List chartList=wordDoc.getCharts(); 这对于条/列/线等来说效果很好。但是,我无法通过这种方法获得瀑布图。所以,我想知道是否有人能解决这个问
List<XWPFChart> chartList = wordDoc.getCharts();
List chartList=wordDoc.getCharts();
这对于条/列/线等来说效果很好。但是,我无法通过这种方法获得瀑布图。所以,我想知道是否有人能解决这个问题?我看到了一些选择
我希望有人已经有了第二个甚至第三个选项的经验?
XWPFChart
是application/vnd.openxmlformats of icedocument.drawingml.chart+xml
类型,而瀑布图是application/vnd.ms office.chartex+xml
类型。这是因为瀑布图是一种扩展的图表类型,在officeopenxml
版本中不可用,而apachepoi
提供了这种类型的图表。我不相信在不久的将来,ApachePOI
会提供这样的扩展图表,因为直到现在,它还没有提供所有类型为application/vnd.openxmlformats of cedocument.drawingml.chart+xml
的本地图表
因此,到目前为止,只有通过直接更改XML,才能在非常低的级别上处理这些图表类型。我在这里和这里展示了一张太阳暴流图 下面的工作草案提供了一个非常基本的类
XWPFChartEx
,到目前为止,它只提供了方法getChartExXmlObject
,该方法将扩展图表的普通XML
作为XmlObject
返回。此XML
可以使用低级XML
方法以编程方式更改。由于XWPFChartEx
扩展了poimmldocumentpart
,因此commit
方法将在document.write(out)
时写入新的Word
文档。它还提供了getWorkbookPart
,返回包含图表数据的xssf工作簿的PackagePart
。此工作簿内容也将更改(如果存在)
文件瀑布图.docx
必须至少有一个瀑布图
import java.io.IOException;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFRelation;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.POIXMLRelation;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.xmlbeans.XmlObject;
public class WordGetWaterfallChart {
static XWPFChartEx getFirstXWPFChartEx(XWPFDocument document) throws Exception {
XWPFChartEx xwpfChartEx = null;
for (POIXMLDocumentPart dpart : document.getRelations()) {
PackagePart ppart = dpart.getPackagePart();
if ("application/vnd.ms-office.chartex+xml".equals(ppart.getContentType())) {
xwpfChartEx = new XWPFChartEx(dpart);
String rId = document.getRelationId(dpart);
document.addRelation(
rId,
new XSSFChartExRelation(
"application/vnd.ms-office.chartex+xml",
"http://schemas.microsoft.com/office/2014/relationships/chartEx",
"/word/charts/chartEx#.xml"),
xwpfChartEx
);
return xwpfChartEx;
}
}
return xwpfChartEx;
}
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument(new FileInputStream("Waterfall_Chart.docx"));
XWPFChartEx waterfallChart = getFirstXWPFChartEx(document);
System.out.println(waterfallChart.getChartExXmlObject());
//TODO: change the XML
System.out.println(waterfallChart.getWorkbookPart());
if (waterfallChart.getWorkbookPart() != null) {
XSSFWorkbook workbook = new XSSFWorkbook(waterfallChart.getWorkbookPart().getInputStream());
for (Sheet sheet : workbook) {
for (Row row : sheet) {
for (Cell cell : row) {
System.out.println(cell);
//TODO: change the cell contents
}
}
}
OutputStream wbOut = waterfallChart.getWorkbookPart().getOutputStream();
workbook.write(wbOut);
wbOut.close();
workbook.close();
}
FileOutputStream out = new FileOutputStream("Waterfall_Chart_Changed.docx");
document.write(out);
out.close();
document.close();
}
private static class XWPFChartEx extends POIXMLDocumentPart {
private XmlObject chartExXmlObject;
private PackagePart workbookPart;
private XWPFChartEx(POIXMLDocumentPart dpart) throws Exception {
super(dpart.getPackagePart());
this.chartExXmlObject = XmlObject.Factory.parse(dpart.getPackagePart().getInputStream());
for (POIXMLDocumentPart.RelationPart rpart : dpart.getRelationParts()) {
if ("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
.equals(rpart.getDocumentPart().getPackagePart().getContentType())) {
this.addRelation(
rpart.getRelationship().getId(),
XWPFRelation.getInstance(rpart.getRelationship().getRelationshipType()),
rpart.getDocumentPart()
);
this.workbookPart = rpart.getDocumentPart().getPackagePart();
}
}
}
private XmlObject getChartExXmlObject() {
return this.chartExXmlObject;
}
private PackagePart getWorkbookPart() {
return this.workbookPart;
}
@Override
protected void commit() throws IOException {
PackagePart part = getPackagePart();
OutputStream out = part.getOutputStream();
chartExXmlObject.save(out);
out.close();
}
}
private static class XSSFChartExRelation extends POIXMLRelation {
private XSSFChartExRelation(String type, String rel, String defaultName) {
super(type, rel, defaultName);
}
}
}
XWPFChart
类型为application/vnd.openxmlformats of icedocument.drawingml.chart+xml
,而瀑布图类型为application/vnd.ms office.chartex+xml
。这是因为瀑布图是一种扩展的图表类型,在officeopenxml
版本中不可用,而apachepoi
提供了这种类型的图表。我不相信在不久的将来,apachepoi
会提供这样的扩展图表,因为到目前为止,它甚至还没有提供所有的本地图表。因此,到目前为止,只有通过直接更改XML
来在非常低的级别上处理这些图表类型的选项。我在这里和这里展示了一张太阳暴流图。嗨,阿克塞尔,谢谢你的快速回复。我看了你关于sunburst Excel图表的答案。我的问题稍有不同,我用的是Word。在Word中,由于您的原因,我目前无法访问瀑布图或您提到的vnd.ms office.chartex+xml类型的图表。棘手的部分是我现在没有一个模板图表可以开始改变,就像你和sunburst图表分享的例子一样。通过scatch的模板在Word中生成此类图表的最佳方式是什么?嗨,Axel,再次感谢您的回复。实际上,我已经在另一个方向上访问不受支持图表的Excel工作表。这是可以做到的,数据也可以修改。我发现令人伤心的是,即使基础数据发生了更改,图表也不会直接刷新。。。单击“编辑数据”将刷新图表,但这将是一种烦人的用户体验。你有解决办法吗?如果是这样,我将坚持这一方针。如果没有,我将尝试实现您刚才发布的答案。@Ivo Sturm:要更改图表数据,必须始终更改/word/charts/chartEx*.XML的XML
,以及/word/embeddings/*.xlsx
中的Excel
数据。请参见我的代码示例中的//TODO
。如果仅更改了两者中的一个,则Word
不会显示更新的图表。