我正在使用ApachePOIJava库(v4.1.1)创建奇妙的Word文档,包括Excel图表。对于Excel图表,我使用Excel模板,并通过ApachePOI库访问Word文档中的图表
List<XWPFChart> chartList = wordDoc.getCharts();
这适用于条形图/柱形图/折线图等。但是,我无法通过这种方法获得瀑布图。所以,我想知道是否有人对此有解决方案?我看到了一些选项;
我希望有人已经有了第二个甚至第三个选择的经验?
XWPFChart
的类型是application/vnd. openxmlforms-officedocument.绘图ml.图表xml
,而瀑布图的类型是application/vnd.ms-office.chartex xml
。这是因为瀑布图是扩展的图表类型,在apache poi
提供的Office OpenXML
版本中不可用。我不相信apache poi
会在不久的将来提供这样的扩展图表,因为它甚至还没有提供application/vnd.openxmlforms-officedocument.绘图ml.图表xml
类型的所有本地图表。
因此,到目前为止,只有通过直接更改XML在非常低的级别上处理这些图表类型的选项。我在这里展示了太阳爆发图表如何通过Apache更改Excel太阳爆发图表中点的图形属性POI以及如何通过ApachePOI设置Excel太阳爆发图表中单个数据标签的文本属性?。
以下工作草案提供了一个非常基本的类XWPFChartEx
,到目前为止,它只提供方法getChartExXmlObject
,它将扩展图表的纯XML
返回为XmlObject
。这个XML
可以使用低级XML
方法以编程方式更改。因为XWPFChartEx
扩展了POIXMLDocumentPart
,它的提交
方法将更改写入新的Word
文档,然后文档. write(out)
。它提供了getWorkbookPart
,它返回包含图表数据的XSSFWorkbook
的PackagePart
。如果存在,此工作簿内容也将被更改。
Waterfall_Chart. 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);
}
}
}