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.*;
@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");
}
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<>();
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) {
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++) {
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;
}
}
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;
}
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);
}
}
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) {
} 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 {
}
}
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);
}
}
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));
}
}
}
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;
}
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;
}
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())));
}
}
}
private static void copyPictures(Sheet newSheet, Sheet sheet) {
Drawing drawingOld = sheet.createDrawingPatriarch();
Drawing drawingNew = newSheet.createDrawingPatriarch();
CreationHelper helper = newSheet.getWorkbook().getCreationHelper();
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);
}
}
}
}
}
}