是否可以使用Apache POI从Office 2007(xlsx / OpenXML)电子表格中提取图表信息?我已经成功阅读了电子表格,甚至获得了引用图表的部分,但不确定如何从此部分检索任何信息,例如图表类型,图表数据等。
XSSFWorkbook xwb = new XSSFWorkbook("charts_lines.xlsx");
XSSFSheet sheet = xwb.getSheetAt(0);
我也可以遍历包裹部分来检索图表部分,但是我不知道如何继续检索有关图表的任何信息?
注意,我对使用POI创建图表不感兴趣,只读取尽可能多的图表信息...我也没有保存xlsx。我只想提取线条颜色,标签,数据,图表类型(饼图,线条,条形图等)
答案 0 :(得分:6)
目前没有高级别的表示,因此您需要下载到xmlbeans级别并使用低级CT *对象。
对于图表表格,有 XSSFChartSheet ,它会为您提供一个CTChartsheet对象,它有一些信息。
对于 XSSFChart 和 XSSFChartSheet (常规和图表),您需要通过图纸来获取图表。每张带有图表的图表都应该有一个图纸,图表会从图纸而不是图纸本身链接。
从r1090442开始(所以POI 3.8或更新版本),XSSFDrawing上有一个方法可以为您提供所有XSSFChart对象(它们是/charts/chart#.xml部分的包装器)。如果您使用的是非常旧版本的POI,请使用CTDrawing获取图表的详细信息,获取对应的/charts/chart#.xml部分,然后让xmlbeans为您提供CT对象。无论哪种方式,都可以让你获得标题,类型,数据范围等。
虽然这有点繁琐,但如果你得到了一些有关CTChart对象的好处,请考虑向POI发送补丁!
答案 1 :(得分:4)
您可以使用XSSFDrawing
喜欢
XSSFDrawing drawing = ((XSSFSheet)sheet).createDrawingPatriarch();
System.out.println(drawing.getCTDrawing().toString());
将整个图表打印为XMl
并使用
drawing.getCharts();
您可以添加Iterator来浏览图表
答案 2 :(得分:2)
我不知道您问题的确切答案,但OpenXML SDK 2.0附带了DocumentReflector.exe
工具,可以准确显示图表的定义方式(包括SpreadsheetML和DrawingML包之间的所有关系) )。 this article中有关于此工具的更多信息。
答案 3 :(得分:0)
是的,可以使用this library读取任何类型的图表。但是,在读取任何图表信息之前,您需要知道接收的XML字符串,因为根据图表类型(饼形图,折线图,条形图,散点图或混合(两个或多个)的图表)的不同,该字符串可能有所不同。因此,您对于不同类型的图表,方法会有所不同。
对于像这样的简单条形图:
您的XML将如下所示:
<xml-fragment ...>
<c:title>
<c:tx>
<c:rich>
...
<a:p>
...
<a:r>
...
<a:t>Employee Salary</a:t>
</a:r>
</a:p>
</c:rich>
</c:tx>
...
</c:title>
...
<c:plotArea>
...
<c:barChart>
...
<c:ser>
...
<c:cat>
<c:strRef>
...
<c:strCache>
<c:ptCount val="5"/>
<c:pt idx="0">
<c:v>Tom</c:v>
</c:pt>
<c:pt idx="1">
<c:v>John</c:v>
</c:pt>
<c:pt idx="2">
<c:v>Harry</c:v>
</c:pt>
<c:pt idx="3">
<c:v>Sam</c:v>
</c:pt>
<c:pt idx="4">
<c:v>Richa</c:v>
</c:pt>
</c:strCache>
</c:strRef>
</c:cat>
<c:val>
<c:numRef>
...
<c:numCache>
<c:formatCode>"$"#,##0</c:formatCode>
<c:ptCount val="5"/>
<c:pt idx="0">
<c:v>1000</c:v>
</c:pt>
<c:pt idx="1">
<c:v>700</c:v>
</c:pt>
<c:pt idx="2">
<c:v>300</c:v>
</c:pt>
<c:pt idx="3">
<c:v>900</c:v>
</c:pt>
<c:pt idx="4">
<c:v>800</c:v>
</c:pt>
</c:numCache>
</c:numRef>
</c:val>
...
</c:ser>
...
</c:barChart>
...
</c:plotArea>
...
</xml-fragment>
现在,基于上述XML字符串,我们可以使用CT *类及其各种方法来使用Apache POI遍历整个XML。让我们看看如何使用POI阅读图表标题,标签(员工姓名)和系列(员工工资):
Workbook workbook = new XSSFWorkbook(new File(PATH));
Sheet sheet = workbook.getSheet("GraphSheet");
XSSFSheet xsheet = (XSSFSheet) sheet;
XSSFDrawing drawing = xsheet.getDrawingPatriarch();
if (drawing != null) {
List<XSSFChart> charts = drawing.getCharts();
for (int chartIndex = 0; charts != null && chartIndex < (charts.size()); chartIndex++) {
XSSFChart chart = charts.get(chartIndex);
CTChart chart2 = chart.getCTChart();
CTPlotArea plot = chart2.getPlotArea();
System.out.println("Chart Title :" + chart2.getTitle().getTx().getRich().getPArray(0).getRArray(0).getT());
CTBarSer[] ctScaSerList = plot.getBarChartArray(0).getSerArray();
for (CTBarSer ctLineSer : ctScaSerList) {
CTStrVal[] ctStrVals = ctLineSer.getCat().getStrRef().getStrCache().getPtArray();
for (int i = 0; i < ctStrVals.length; i++) {
System.out.print(ctStrVals[i].getV() + ",");
}
System.out.println();
CTNumVal[] ctXNumVal = ctLineSer.getVal().getNumRef().getNumCache().getPtArray();
for (int i = 0; i < ctXNumVal.length; i++) {
System.out.print(ctXNumVal[i].getV() + ",");
}
}
}
}
控制台:
Chart Title :Employee Salary
Tom,John,Harry,Sam,Richa,
1000,700,300,900,800,
注意:这里的想法是首先读取XML字符串(因为根据您的图形类型可能会有所不同),然后然后遍历整个XML 。< / p>