public List<Map<String, Object>> parseExcelData(MultipartFile file) {
List<Map<String, Object>> dataList = Lists.newArrayList();
try (InputStream inputStream = file.getInputStream()) {
Workbook workbook = WorkbookFactory.create(inputStream);
Sheet sheet = workbook.getSheetAt(0);
Map<CellPosition, byte[]> embeddedObjects = new HashMap<>();
if (workbook instanceof HSSFWorkbook) {
embeddedObjects = extractHSSFObjects((HSSFSheet) sheet);
} else if (workbook instanceof XSSFWorkbook) {
List<CellPosition> positionList = getObjectCellPositions((XSSFSheet) sheet);
embeddedObjects = extractXSSFObjects((XSSFWorkbook) workbook, positionList);
}
} catch (ServiceException e) {
log.error("CaSpecialAgreementExcelImport[]importExcel[]ServiceException[]is error,cause:{}", Throwables.getStackTraceAsString(e));
throw new ServiceException(e.getMessage());
}
}
// HSSF对象提取 private Map<CellPosition, byte[]> extractHSSFObjects(HSSFSheet sheet) { Map<CellPosition, byte[]> result = new HashMap<>(); HSSFPatriarch drawing = sheet.getDrawingPatriarch(); if (drawing == null) { return null; }
for (HSSFShape shape : drawing.getChildren()) {
if (shape instanceof HSSFObjectData) {
HSSFObjectData obj = (HSSFObjectData) shape;
CellPosition pos = getObjectCellPosition(obj);
result.put(pos, obj.getObjectData());
}
}
return result;
}
/**
-
获取嵌入对象对应的单元格位置(近似匹配行范围)
-
@param objectData 嵌入对象
-
@return 单元格位置(行、列) / /*
-
获取嵌入对象对应的单元格位置(近似匹配行范围)
-
@param objectData 嵌入对象
-
@return 单元格位置(行、列) */ private CellPosition getObjectCellPosition(HSSFObjectData objectData) { try { // 从对象的锚点获取位置信息 HSSFAnchor anchor = objectData.getAnchor(); if (anchor == null) return null;
// 检查是否为客户端锚点类型 if (anchor instanceof HSSFClientAnchor) { HSSFClientAnchor clientAnchor = (HSSFClientAnchor) anchor; // 获取锚点的起始行、列 int row = clientAnchor.getRow1(); int col = clientAnchor.getCol1(); // 返回单元格位置 return new CellPosition(row, col); }} catch (Exception e) { // 打印错误日志 log.error("解析嵌入对象位置失败: {}", e.getMessage()); } // 返回null return null; }
/** *
-
获取XSSFSheet中的对象位置
-
@param sheet
-
@return
-
@throws IOException */ private List getObjectCellPositions(XSSFSheet sheet) throws IOException { XSSFDrawing drawing = sheet.getDrawingPatriarch(); if (drawing == null) { return null; } List result = new ArrayList<>();
// 遍历绘图中的所有形状 for (XSSFShape shape : drawing.getShapes()) { // 如果形状是XSSFObjectData类型的实例 if (shape instanceof XSSFObjectData) { XSSFObjectData objData = (XSSFObjectData) shape; // 使用getAnchor()方法替代findAnchor(),获取形状的锚点 XSSFClientAnchor anchor = (XSSFClientAnchor) shape.getAnchor(); if (anchor == null) { continue; } // 创建CellPosition对象,记录附件的位置 CellPosition pos = new CellPosition(anchor.getRow1(), anchor.getCol1());
result.add(pos); }}
return result; }
/**
* 提取XSSFWorkbook中的对象
*
* @param workbook
* @param positionList
* @return
*/
private Map<CellPosition, byte[]> extractXSSFObjects(XSSFWorkbook workbook, List<CellPosition> positionList) {
Map<CellPosition, byte[]> embeddedObjects = new HashMap<>();
try {
List<PackagePart> allEmbeddedParts = workbook.getAllEmbeddedParts();
for (int i = 0; i < allEmbeddedParts.size(); i++) {
PackagePart part = allEmbeddedParts.get(i);
try (InputStream emb = part.getInputStream()) {
POIFSFileSystem fs = new POIFSFileSystem(emb);
byte[] fileData = null;
String fileName = null;
DirectoryNode root = fs.getRoot();
// 方案1: 尝试标准Ole10Native解析
// 方案2: 处理非标准结构(ObjInfo+package)
// 方案3: 处理纯Ole对象
// pdf文件直接读取\u0001Ole10Native流
// word文件处理\u0001ObjInfo+package流
// excel文件处理\u0001ObjInfo+package流
// 图片文件处理\u0001FileEntryStream流
if (root.hasEntry("\u0001Ole10Native")) {
Ole10Native ole = Ole10Native.createFromEmbeddedOleObject(root);
fileData = ole.getDataBuffer();
fileName = ole.getLabel2();
} else if (root.hasEntry("\u0001ObjInfo")) {
try (InputStream is = fs.createDocumentInputStream("\u0001ObjInfo")) {
fileData = IOUtils.toByteArray(is);
fileName = new String(fileData, StandardCharsets.UTF_16LE);
fileName = fileName.substring(fileName.indexOf(':') + 1).trim();
}
} else if (root.hasEntry("\u0001Ole")) {
try (InputStream is = fs.createDocumentInputStream("\u0001Ole")) {
fileData = IOUtils.toByteArray(is);
}
} else if (root.hasEntry("\u0001FileEntryStream")) {
try (InputStream is = fs.createDocumentInputStream("\u0001FileEntryStream")) {
fileData = IOUtils.toByteArray(is);
fileName = part.getPartName().getName();
}
} else {
log.error("CaSpecialAgreementExcelImport[]parseResponsibility unsupported embedded object type");
continue;
}
if (fileData != null) {
// 获取原文件名称
CellPosition cellPosition = positionList.get(i);
cellPosition.setFileName(fileName);
embeddedObjects.put(cellPosition, fileData);
}
}
}
} catch (OpenXML4JException e) {
log.error("CaSpecialAgreementExcelImport[]extracted error,cause:{}", Throwables.getStackTraceAsString(e));
} catch (Exception e) {
log.error("CaSpecialAgreementExcelImport[]parseResponsibility parse embedded object error,cause:{}", Throwables.getStackTraceAsString(e));
}
return embeddedObjects;
}
```