java 如何解析导入excel中的对象附件,并下载到本地,只支持pdf文件

114 阅读2分钟
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;
}
```