如何使用Apache POI从xls文件中获取名称的图片

使用workbook.getAllPictures()我可以得到一个图片数据的数组,但不幸的是,它只是数据,这些对象没有方法来访问图片的名称或任何其他相关的信息。

有一个HSSFPicture类将包含图片的所有细节,但如何得到例如从xls的这些对象的数组?

更新:

发现SO问题如何find一个单元格,其中包含一个图片在apache poi有一个方法循环在工作表中的所有图片。 这样可行。

现在,我可以尝试HSSFPicture类,我发现getFileName()方法返回的文件名没有扩展名。 我可以使用getPictureData().suggestFileExtension()来获得一个build议的文件扩展名,但是我真的需要获得图片在添加到xls文件时的扩展名。 会有办法得到它吗?

更新2:

图片被添加到一个macros的xls。 这是将图像添加到工作表的macros的一部分。 fname是完整path, imageName是文件名,两者都包含扩展名。

 Set img = Sheets("Receipt images").Pictures.Insert(fname) img.Left = 10 img.top = top + 10 img.Name = imageName Set img = Nothing 

例程检查图片是否已经存在于Excel文件中。

 For Each img In Sheets("Receipt images").Shapes If img.Name = imageName Then Set foundImage = img Exit For End If Next 

这认识到“image.jpg”不同于“image.gif”,所以img.Name包含扩展名。

形状名称不在默认的POI对象中。 所以如果我们需要他们,我们必须处理底层对象。 这是HSSF中的形状主要是我们可以从工作表中获得的EscherAggregate( http://poi.apache.org/apidocs/org/apache/poi/hssf/record/EscherAggregate.html )。 从其父类AbstractEscherHolderRecord中,我们可以获得包含形状选项的所有EscherOptRecords。 在这些选项中还可以findgroupshape.shapenames。

我的例子不是完整的解决scheme。 它只提供显示哪些对象可以用来实现这一点。

例:

 import org.apache.poi.hssf.usermodel.*; import org.apache.poi.ss.usermodel.*; import java.io.FileOutputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.FileInputStream; import java.io.InputStream; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.hssf.record.*; import org.apache.poi.ddf.*; import java.util.List; import java.util.ArrayList; class ShapeNameTestHSSF { public static void main(String[] args) { try { InputStream inp = new FileInputStream("workbook1.xls"); Workbook wb = WorkbookFactory.create(inp); Sheet sheet = wb.getSheetAt(0); EscherAggregate escherAggregate = ((HSSFSheet)sheet).getDrawingEscherAggregate(); EscherContainerRecord escherContainer = escherAggregate.getEscherContainer().getChildContainers().get(0); //throws java.lang.NullPointerException if no Container present List<EscherRecord> escherOptRecords = new ArrayList<EscherRecord>(); escherContainer.getRecordsById(EscherOptRecord.RECORD_ID, escherOptRecords); for (EscherRecord escherOptRecord : escherOptRecords) { for (EscherProperty escherProperty : ((EscherOptRecord)escherOptRecord).getEscherProperties()) { System.out.println(escherProperty.getName()); if (escherProperty.isComplex()) { System.out.println(new String(((EscherComplexProperty)escherProperty).getComplexData(), "UTF-16LE")); } else { if (escherProperty.isBlipId()) System.out.print("BlipId = ImageId = "); System.out.println(((EscherSimpleProperty)escherProperty).getPropertyValue()); } System.out.println("============================="); } System.out.println(":::::::::::::::::::::::::::::"); } FileOutputStream fileOut = new FileOutputStream("workbook1.xls"); wb.write(fileOut); fileOut.flush(); fileOut.close(); } catch (InvalidFormatException ifex) { } catch (FileNotFoundException fnfex) { } catch (IOException ioex) { } } } 

再说一遍:这不是一个随时可用的解决scheme。 由于EscherRecords的复杂性,在这里不能提供现成的解决scheme。 也许为图像形状及其相关的EscherOptRecords获取正确的EscherRecords,您将recursion地遍历EscherAggregate中的所有EscherRecords,检查它们是否为ContainerRecords,如果是,则遍历其子节点等等。

从这里开始:

http://poi.apache.org/spreadsheet/quick-guide.html#Images

本教程可以帮助您使用Apache POI从xls电子表格中提取图像的信息