poi合并多个excel文件,并且排序

package com.envisioniot.reportds.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor;

import java.io.*;
import java.util.*;

/**
 * @author YangHaojie
 * @date 2021/8/30
 */
@Slf4j
public class ExcelUtils {

    public static void main(String[] args) {
        File[] files = new File[3];
        files[0] = new File("C:\\Users\\TemplatePreview_20210830 (1).xlsx");
        files[1] = new File("C:\\Users\\TemplatePreview_20210830.xlsx");
        files[2] = new File("C:\\Users\\\\新建 Microsoft Excel 工作表.xlsx");
        mergexcel(files,"test.xlsx","C:\\Users\\\\excel_test\\");
        System.out.println("OJBK");
    }

    /**
     * * 合并多个ExcelSheet
     *
     * @param files 文件字符串(file.toString)集合,按顺序进行合并,合并的Excel中Sheet名称不可重复
     * @param excelName 合并后Excel名称(包含后缀.xslx)
     * @param dirPath 存储目录
     */
    public static boolean mergexcel(File[] files, String excelName, String dirPath) {
        if(files == null){
            return false;
        }
        Arrays.sort(files, new Comparator<File>() {
            @Override
            public int compare(File o1, File o2) {
                if (o1.isDirectory() && o2.isFile()) {
                    return -1;
                }
                if (o1.isFile() && o2.isDirectory()) {
                    return 1;
                }
                String o1Name = o1.getName().substring(0, o1.getName().lastIndexOf(".") > 0 ?
                        o1.getName().lastIndexOf(".") : o1.getName().length());
                String o2Name = o2.getName().substring(0, o2.getName().lastIndexOf(".") > 0 ?
                        o2.getName().lastIndexOf(".") : o2.getName().length());
                return o1Name.compareTo(o2Name);
            }
        });
        XSSFWorkbook newExcelCreat = new XSSFWorkbook();
        Map<String, Integer> names = new HashMap<>();
        // 遍历每个源excel文件,TmpList为源文件的名称集合
        for (File fromExcelFile : files) {
            if(fromExcelFile == null){
                continue;
            }
            String fromExcelName = fromExcelFile.toString();
            String name = fromExcelFile.getName();
            if(StringUtils.isNotEmpty(name)){
                name = name.substring(0, name.lastIndexOf(".") != 0 ? name.lastIndexOf(".") : name.length());
            }
            try (InputStream in = new FileInputStream(fromExcelName)) {
                XSSFWorkbook fromExcel = new XSSFWorkbook(in);
                int length = fromExcel.getNumberOfSheets();
                if (length == 1) {       //长度为1时
                    XSSFSheet oldSheet = fromExcel.getSheetAt(0);
                    if(names.containsKey(name)){
                        int cnt = names.get(name) + 1;
                        name = name.concat("(").concat(String.valueOf(cnt)).concat(")");
                    }
                    names.put(name, names.getOrDefault(name, 0) + 1);
                    XSSFSheet newSheet = newExcelCreat.createSheet(name);
                    copySheet(newExcelCreat, oldSheet, newSheet);
                    copyPicture(newExcelCreat, oldSheet, newSheet);
                } else {
                    for (int i = 0; i < length; i++) {// 遍历每个sheet
                        XSSFSheet oldSheet = fromExcel.getSheetAt(i);
                        if(names.containsKey(name)){
                            int cnt = names.get(name) + 1;
                            name = name.concat("(").concat(String.valueOf(cnt)).concat(")");
                        }
                        names.put(name, names.getOrDefault(name, 0) + 1);
                        XSSFSheet newSheet = newExcelCreat.createSheet(name);
                        copySheet(newExcelCreat, oldSheet, newSheet);
                        copyPicture(newExcelCreat, oldSheet, newSheet);
                    }
                }
            } catch (Exception e) {
                log.error("excel merge failed", e);
                return false;
            }
        }
        // 定义新生成的xlxs表格文件
        String allFileName = dirPath + excelName;
        try (FileOutputStream fileOut = new FileOutputStream(allFileName)) {
            newExcelCreat.write(fileOut);
            fileOut.flush();
        } catch (Exception e) {
            log.error("excel merge failed", e);
            return false;
        } finally {
            try {
                newExcelCreat.close();
            } catch (IOException e) {
                log.error("excel merge failed", e);
                return false;
            }
        }
        return true;
    }

    /**
     * 合并单元格
     *
     * @param fromSheet
     * @param toSheet
     */
    private static void mergeSheetAllRegion(XSSFSheet fromSheet, XSSFSheet toSheet) {
        int num = fromSheet.getNumMergedRegions();
        CellRangeAddress cellR = null;
        for (int i = 0; i < num; i++) {
            cellR = fromSheet.getMergedRegion(i);
            toSheet.addMergedRegion(cellR);
        }
    }

    /**
     * 复制单元格
     *
     * @param wb
     * @param fromCell
     * @param toCell
     */
    private static void copyCell(XSSFWorkbook wb, XSSFCell fromCell, XSSFCell toCell) {
        XSSFCellStyle newstyle = wb.createCellStyle();
        // 复制单元格样式
        newstyle.cloneStyleFrom(fromCell.getCellStyle());
        // 样式
        toCell.setCellStyle(newstyle);
        if (fromCell.getCellComment() != null) {
            toCell.setCellComment(fromCell.getCellComment());
        }
        // 不同数据类型处理
        CellType fromCellType = fromCell.getCellType();
        toCell.setCellType(fromCellType);
        if (fromCellType == CellType.NUMERIC) {
            if (DateUtil.isCellDateFormatted(fromCell)) {
                toCell.setCellValue(fromCell.getDateCellValue());
            } else {
                toCell.setCellValue(fromCell.getNumericCellValue());
            }
        } else if (fromCellType == CellType.STRING) {
            toCell.setCellValue(fromCell.getRichStringCellValue());
        } else if (fromCellType == CellType.BLANK) {
            // nothing21
        } else if (fromCellType == CellType.BOOLEAN) {
            toCell.setCellValue(fromCell.getBooleanCellValue());
        } else if (fromCellType == CellType.ERROR) {
            toCell.setCellErrorValue(fromCell.getErrorCellValue());
        } else if (fromCellType == CellType.FORMULA) {
            toCell.setCellFormula(fromCell.getCellFormula());
        } else {
            // nothing
        }
    }

    /**
     * 行复制功能
     *
     * @param wb
     * @param oldRow
     * @param toRow
     */
    private static void copyRow(XSSFWorkbook wb, XSSFRow oldRow, XSSFRow toRow) {
        //设置行高
        toRow.setHeight(oldRow.getHeight());
        for (Iterator cellIt = oldRow.cellIterator(); cellIt.hasNext(); ) {
            XSSFCell tmpCell = (XSSFCell) cellIt.next();
            XSSFCell newCell = toRow.createCell(tmpCell.getColumnIndex());
            copyCell(wb, tmpCell, newCell);
        }
    }

    /**
     * Sheet复制
     *
     * @param wb
     * @param fromSheet
     * @param toSheet
     */
    private static void copySheet(XSSFWorkbook wb, XSSFSheet fromSheet, XSSFSheet toSheet) {
        mergeSheetAllRegion(fromSheet, toSheet);
        int maxColumnNum = 0;
        for (Iterator rowIt = fromSheet.rowIterator(); rowIt.hasNext(); ) {
            XSSFRow oldRow = (XSSFRow) rowIt.next();
            XSSFRow newRow = toSheet.createRow(oldRow.getRowNum());
            copyRow(wb, oldRow, newRow);
            if(oldRow.getLastCellNum() > maxColumnNum){
                maxColumnNum = oldRow.getLastCellNum();
            }
        }
        //设置列宽
        if(fromSheet != null && toSheet != null) {
            for (int i = 0; i <= maxColumnNum; i++) {
                toSheet.setColumnWidth(i, fromSheet.getColumnWidth(i));
            }
        }
    }

    /**
     * 获取图片和位置 (xlsx),会复原图片大小
     * @param sheet
     * @return
     * @throws IOException
     */
    public static Map<String, XSSFPictureData> getPictures (XSSFSheet sheet) throws IOException {
        Map<String, XSSFPictureData> map = new HashMap<String, XSSFPictureData>();
        List<POIXMLDocumentPart> list = sheet.getRelations();
        for (POIXMLDocumentPart part : list) {
            if (part instanceof XSSFDrawing) {
                XSSFDrawing drawing = (XSSFDrawing) part;
                List<XSSFShape> shapes = drawing.getShapes();
                for (XSSFShape shape : shapes) {
                    XSSFPicture picture = (XSSFPicture) shape;
                    XSSFClientAnchor anchor = picture.getPreferredSize();
                    CTMarker marker = anchor.getFrom();
                    String key = marker.getRow() + "-" + marker.getCol();
                    map.put(key, picture.getPictureData());
                }
            }
        }
        return map;
    }

    /**
     * 获得原始sheet中图片的信息、位置 todo:解决图片的格式以及属性
     * @param sheet
     * @return
     * @throws IOException
     */
    public static List<Map<String,Object>> getPicturesFromXSSFSheet (XSSFSheet sheet) throws IOException {
        List<Map<String,Object>> res = new ArrayList<>();
        List<POIXMLDocumentPart> list = sheet.getRelations();
        for (POIXMLDocumentPart part : list) {
            if (part instanceof XSSFDrawing) {
                XSSFDrawing drawing = (XSSFDrawing) part;
                List<XSSFShape> shapes = drawing.getShapes();
                for (XSSFShape shape : shapes) {
                    Map<String,Object> map = new HashMap<>();
                    XSSFPicture picture = (XSSFPicture) shape;
                    XSSFClientAnchor anchor = picture.getClientAnchor();
                    map.put("pictureAnchor", anchor);
                    map.put("pictureByteArray", picture.getPictureData().getData());
                    map.put("pictureType", picture.getPictureData().getPictureType());
                    res.add(map);
                    picture.getCTPicture();
                }
            }
        }
        return res;
    }

    /**
     * 复制图片
     * @param workbook
     * @param sourceSheet
     * @param targetSheet
     * @throws IOException
     */
    public static void copyPicture(XSSFWorkbook workbook,XSSFSheet sourceSheet,XSSFSheet targetSheet) throws IOException {
        XSSFDrawing drawing = targetSheet.createDrawingPatriarch();
        List< Map<String,Object>> sourceSheetPictures=getPicturesFromXSSFSheet(sourceSheet);
        if(CollectionUtils.isNotEmpty(sourceSheetPictures)){
            for(Map<String, Object> sourceSheetPicture : sourceSheetPictures) {
                if(sourceSheetPicture == null || sourceSheetPicture.size() == 0){
                    continue;
                }
                XSSFPicture picture = drawing.createPicture((XSSFClientAnchor) sourceSheetPicture.get("pictureAnchor"),
                        workbook.addPicture((byte[]) sourceSheetPicture.get("pictureByteArray"),
                                Integer.parseInt(sourceSheetPicture.get("pictureType").toString())));

            }
        }
    }

    /**
     * 复制图片方法2
     * @param newSheet
     * @param sheet
     */
    private static void copyPictures(Sheet newSheet, Sheet sheet) {
        Drawing drawingOld = sheet.createDrawingPatriarch();
        Drawing drawingNew = newSheet.createDrawingPatriarch();
        CreationHelper helper = newSheet.getWorkbook().getCreationHelper();
        // if (drawingNew instanceof HSSFPatriarch) {
        if (drawingOld instanceof HSSFPatriarch) {
            List<HSSFShape> shapes = ((HSSFPatriarch) drawingOld).getChildren();
            for (int i = 0; i < shapes.size(); i++) {
                if (shapes.get(i) instanceof HSSFPicture) {
                    HSSFPicture pic = (HSSFPicture) shapes.get(i);
                    HSSFPictureData picdata = pic.getPictureData();
                    int pictureIndex = newSheet.getWorkbook().addPicture(picdata.getData(), picdata.getFormat());
                    ClientAnchor anchor = null;
                    if (pic.getAnchor() != null) {
                        anchor = helper.createClientAnchor();
                        anchor.setDx1(((HSSFClientAnchor) pic.getAnchor()).getDx1());
                        anchor.setDx2(((HSSFClientAnchor) pic.getAnchor()).getDx2());
                        anchor.setDy1(((HSSFClientAnchor) pic.getAnchor()).getDy1());
                        anchor.setDy2(((HSSFClientAnchor) pic.getAnchor()).getDy2());
                        anchor.setCol1(((HSSFClientAnchor) pic.getAnchor()).getCol1());
                        anchor.setCol2(((HSSFClientAnchor) pic.getAnchor()).getCol2());
                        anchor.setRow1(((HSSFClientAnchor) pic.getAnchor()).getRow1());
                        anchor.setRow2(((HSSFClientAnchor) pic.getAnchor()).getRow2());
                        anchor.setAnchorType(((HSSFClientAnchor) pic.getAnchor()).getAnchorType());
                    }
                    drawingNew.createPicture(anchor, pictureIndex);
                }
            }
        } else {
            if (drawingNew instanceof XSSFDrawing) {
                List<XSSFShape> shapes = ((XSSFDrawing) drawingOld).getShapes();
                for (int i = 0; i < shapes.size(); i++) {
                    if (shapes.get(i) instanceof XSSFPicture) {
                        XSSFPicture pic = (XSSFPicture) shapes.get(i);
                        XSSFPictureData picdata = pic.getPictureData();
                        int pictureIndex = newSheet.getWorkbook().addPicture(picdata.getData(),
                                picdata.getPictureType());
                        XSSFClientAnchor anchor = null;
                        CTTwoCellAnchor oldAnchor = ((XSSFDrawing) drawingOld).getCTDrawing().getTwoCellAnchorArray(i);
                        if (oldAnchor != null) {
                            anchor = (XSSFClientAnchor) helper.createClientAnchor();
                            CTMarker markerFrom = oldAnchor.getFrom();
                            CTMarker markerTo = oldAnchor.getTo();
                            anchor.setDx1((int) markerFrom.getColOff());
                            anchor.setDx2((int) markerTo.getColOff());
                            anchor.setDy1((int) markerFrom.getRowOff());
                            anchor.setDy2((int) markerTo.getRowOff());
                            anchor.setCol1(markerFrom.getCol());
                            anchor.setCol2(markerTo.getCol());
                            anchor.setRow1(markerFrom.getRow());
                            anchor.setRow2(markerTo.getRow());
                        }
                        drawingNew.createPicture(anchor, pictureIndex);
                    }
                }
            }
        }
    }

}

你可能感兴趣的:(java)