如何从excel表中选择复选框值

我正在处理一个与阅读excel相关的任务,其中包含单选按钮和使用Java的复选框,我已经尝试了很多但是无法继续进行此操作,当我尝试读取包含Checkbox的单元格的数据时它返回了空值。

在此处输入图像描述

有人可以帮忙解决这个问题。

控件不包含在单元格中,而是作为形状hover在工作表上的绘图层中,并且仅锚定到单元格。 因此,单元格可能为空(因为其中没有内容),尽管形状hover在其上并锚定在其上。

此外,有两种不同的控制可能。 有表单控件和ActiveX控件。 ActiveX控件的状态存储在二进制代码部分activeX1.bin ,因此获取它们的状态非常困难。

在早期的Excel版本(例如2007)中,所有控件的锚信息仅存储在/xl/drawings/vmlDrawing1.vml 。 更高版本将它们存储在默认图形中

   ...   

表格中的部分也是XML 。 幸运的是,还有/xl/drawings/vmlDrawing1.vml用于向后兼容。

以下代码解析/xl/drawings/vmlDrawing1.vml以获取可能锚定到单元格的控件。 如果找到,它将获得此控件,如果此控件是表单控件而不是 ActiveX控件,那么它也可以获取它的状态。 对于ActiveX控件,它只获取“Pict”锚定到此单元格的信息。

Excel中:

在此处输入图像描述

码:

 import java.io.*; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.*; import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.util.Units; import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlObject; import javax.xml.namespace.QName; class ReadExcelXSSFControls { public ReadExcelXSSFControls() throws Exception { XSSFWorkbook wb = (XSSFWorkbook)WorkbookFactory.create(new FileInputStream("ExcelWithControls.xlsx")); Sheet sheet = wb.getSheetAt(0); for (Row row : sheet) { for (int c = 0; c < 2; c++) { Cell cell = row.getCell(c); if (row.getRowNum() == 0) { System.out.print(cell + "\t"); } else { if (c == 0) { System.out.print(cell + "\t"); } else if (c == 1) { if (cell == null) cell = row.createCell(c); Control contol = getControlAt((XSSFCell)cell); System.out.print(contol); } } } System.out.println(); } wb.close(); } private Control getControlAt(XSSFCell cell) throws Exception { XSSFSheet sheet = cell.getSheet(); Row row = cell.getRow(); int r = row.getRowNum(); int c = cell.getColumnIndex(); int drheight = (int)Math.round(sheet.getDefaultRowHeightInPoints() * Units.PIXEL_DPI / Units.POINT_DPI); int rheight = (int)Math.round(row.getHeightInPoints() * Units.PIXEL_DPI / Units.POINT_DPI); row = null; if(r > 0) row = sheet.getRow(r-1); int rheightbefore = (row!=null)?(int)Math.round(row.getHeightInPoints() * Units.PIXEL_DPI / Units.POINT_DPI):drheight; row = sheet.getRow(r+1); int rheightafter = (row!=null)?(int)Math.round(row.getHeightInPoints() * Units.PIXEL_DPI / Units.POINT_DPI):drheight; String name = null; String objectType = null; String checked = null; XmlCursor xmlcursor = null; if (sheet.getCTWorksheet().getLegacyDrawing() != null) { String legacyDrawingId = sheet.getCTWorksheet().getLegacyDrawing().getId(); POIXMLDocumentPart part = sheet.getRelationById(legacyDrawingId); XmlObject xmlDrawing = XmlObject.Factory.parse(part.getPackagePart().getInputStream()); xmlcursor = xmlDrawing.newCursor(); QName qnameClientData = new QName("urn:schemas-microsoft-com:office:excel", "ClientData", "x"); QName qnameAnchor = new QName("urn:schemas-microsoft-com:office:excel", "Anchor", "x"); boolean controlFound = false; while (xmlcursor.hasNextToken()) { XmlCursor.TokenType tokentype = xmlcursor.toNextToken(); if (tokentype.isStart()) { if (qnameClientData.equals(xmlcursor.getName())) { controlFound = true; XmlObject clientdata = xmlcursor.getObject(); XmlObject[] xmlchecked = clientdata.selectPath("declare namespace x='urn:schemas-microsoft-com:office:excel' x:Checked"); if (xmlchecked.length > 0) { checked = "Checked"; } else { checked = "Not checked"; } while (xmlcursor.hasNextToken()) { tokentype = xmlcursor.toNextToken(); if (tokentype.isAttr()) { if (new QName("ObjectType").equals(xmlcursor.getName())) { objectType = xmlcursor.getTextValue(); name = objectType + " in row " + (r+1); } } else { break; } } } else if (qnameAnchor.equals(xmlcursor.getName()) && controlFound) { controlFound = false; String anchorContent = xmlcursor.getTextValue().trim(); String[] anchorparts = anchorContent.split(","); int fromCol = Integer.parseInt(anchorparts[0].trim()); int fromColDx = Integer.parseInt(anchorparts[1].trim()); int fromRow = Integer.parseInt(anchorparts[2].trim()); int fromRowDy = Integer.parseInt(anchorparts[3].trim()); int toCol = Integer.parseInt(anchorparts[4].trim()); int toColDx = Integer.parseInt(anchorparts[5].trim()); int toRow = Integer.parseInt(anchorparts[6].trim()); int toRowDy = Integer.parseInt(anchorparts[7].trim()); if (fromCol == c /*needs only starting into the column*/ && (fromRow == r || (fromRow == r-1 && fromRowDy > rheightbefore/2f)) && (toRow == r || (toRow == r+1 && toRowDy < rheightafter/2f))) { //System.out.print(fromCol + ":" +fromColDx + ":" + fromRow + ":" + fromRowDy + ":" + toCol + ":" + toColDx + ":" + toRow + ":" + toRowDy); break; } } } } } if (xmlcursor!=null && xmlcursor.hasNextToken()) return new Control(name, objectType, checked, r, c); return new Control("Not found", "unknown", "undefined", r, c); } public static void main(String[] args) throws Exception { ReadExcelXSSFControls o = new ReadExcelXSSFControls(); } private class Control { private String name; private String objectType; private String checked; private int row; private int col; public Control(String name, String objectType, String checked, int row, int col) { this.name = name; this.objectType = objectType; this.checked = checked; this.row = row; this.col= col; } public String getName() { return this.name; } public String getObjectType() { return this.objectType; } public String getChecked() { return this.checked; } public int getRow() { return this.row; } public int getCol() { return this.col; } public String toString() { return this.name + ":r/c:" +row+ "/" + col + ":" + this.checked; } } } 

结果:

 axel@arichter:~/Dokumente/JAVA/poi/poi-3.17$ java -cp .:./*:./lib/*:./ooxml-lib/* ReadExcelXSSFControls Product Status a Checkbox in row 2:r/c:1/1:Checked b Not found:r/c:2/1:undefined c Checkbox in row 4:r/c:3/1:Not checked d Checkbox in row 5:r/c:4/1:Checked e Radio in row 6:r/c:5/1:Checked f Not found:r/c:6/1:undefined g Not found:r/c:7/1:undefined e Checkbox in row 9:r/c:8/1:Checked f Not found:r/c:9/1:undefined h Radio in row 11:r/c:10/1:Not checked ActiveX Pict in row 14:r/c:13/1:Not checked