988 lines
39 KiB
Java
988 lines
39 KiB
Java
package com.zhgd.xmgl.util;
|
||
|
||
import com.zhgd.jeecg.common.mybatis.EntityMap;
|
||
import com.zhgd.xmgl.modules.car.entity.CarType;
|
||
import com.zhgd.xmgl.modules.exam.entity.ExamSubject;
|
||
import com.zhgd.xmgl.modules.safetyhat.entity.SafetyHatFence;
|
||
import com.zhgd.xmgl.modules.worker.entity.EnterpriseInfo;
|
||
import com.zhgd.xmgl.modules.worker.entity.WorkerSafeEducationWorker;
|
||
import com.zhgd.xmgl.modules.worker.entity.WorkerType;
|
||
import com.zhgd.xmgl.modules.worker.entity.dto.WorkerAttendanceDto;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.apache.commons.collections.MapUtils;
|
||
import org.apache.commons.lang3.StringUtils;
|
||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
|
||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||
import org.apache.poi.ss.usermodel.*;
|
||
import org.apache.poi.ss.util.CellRangeAddress;
|
||
import org.apache.poi.util.IOUtils;
|
||
import org.apache.poi.xssf.usermodel.*;
|
||
import org.springframework.core.io.ClassPathResource;
|
||
|
||
import javax.servlet.http.HttpServletResponse;
|
||
import java.io.*;
|
||
import java.net.URLEncoder;
|
||
import java.util.*;
|
||
|
||
/**
|
||
* @program: wisdomSite
|
||
* @description: excel处理工具类
|
||
* @author: Mr.Peng
|
||
* @create: 2021-08-16 17:42
|
||
**/
|
||
@Slf4j
|
||
public class ExcelUtils {
|
||
|
||
public static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) throws IOException {
|
||
response.setCharacterEncoding("UTF-8");
|
||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
|
||
workbook.write(response.getOutputStream());
|
||
}
|
||
|
||
public static List<Map<String, String>> jxlExlToList(InputStream is, int index) throws Exception {
|
||
Workbook book = null;
|
||
List<Map<String, String>> list = null;
|
||
String companyId = null;
|
||
//Map<String,Object> map=new HashMap<>(16);
|
||
try {
|
||
book = WorkbookFactory.create(is);
|
||
//book = new XSSFWorkbook(is);// 创建一个新的写入工作簿
|
||
Sheet sheet = book.getSheetAt(0);
|
||
//int totalRows = sheet.getLastRowNum();
|
||
int totalRows = sheet.getPhysicalNumberOfRows();
|
||
//int totalColumns = sheet.getColumns();
|
||
Row xssfRow = sheet.getRow(index);
|
||
int totalColumns = xssfRow.getLastCellNum();
|
||
if (totalColumns <= 0) {
|
||
return null;
|
||
}
|
||
//读取指定行作为Map中的key
|
||
List<String> tableHeaderlist = new ArrayList<>();
|
||
for (int i = 0; i < totalColumns; i++) {
|
||
String value = getCellValue(sheet, xssfRow.getCell(i));
|
||
if (tableHeaderlist.contains(value)) {
|
||
value = value + "(1)";
|
||
}
|
||
if (StringUtils.isNotEmpty(value)) {
|
||
value = value.replaceAll("[\\t\\n\\r]", "");
|
||
}
|
||
tableHeaderlist.add(value);
|
||
}
|
||
//将指定行后面每一行存为Map集合,然后存为list
|
||
list = new ArrayList<>();
|
||
Map<String, String> rowData = new LinkedHashMap<>();
|
||
int start = 1 + index;
|
||
for (int i = start; i < totalRows; i++) {
|
||
xssfRow = sheet.getRow(i);
|
||
rowData = new LinkedHashMap<>(totalColumns);
|
||
|
||
for (int j = 0; j < xssfRow.getLastCellNum(); j++) {
|
||
if (j < totalColumns) {
|
||
if (StringUtils.isNotEmpty(tableHeaderlist.get(j).toString())) {
|
||
if (xssfRow.getCell(j) != null) {
|
||
String value = getCellValue(sheet, xssfRow.getCell(j));
|
||
rowData.put(tableHeaderlist.get(j).toString(), value);
|
||
} else {
|
||
rowData.put(tableHeaderlist.get(j).toString(), "");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (rowData.size() > 0) {
|
||
list.add(rowData);
|
||
}
|
||
|
||
}
|
||
|
||
log.info("工作簿读取数据成功!");
|
||
} catch (Exception e) {
|
||
log.error("error:", e);
|
||
}
|
||
return list;
|
||
}
|
||
|
||
public static String getMergedRegionValue(Sheet sheet, int row, int column) {
|
||
int sheetMergeCount = sheet.getNumMergedRegions();
|
||
|
||
for (int i = 0; i < sheetMergeCount; i++) {
|
||
CellRangeAddress ca = sheet.getMergedRegion(i);
|
||
int firstColumn = ca.getFirstColumn();
|
||
int lastColumn = ca.getLastColumn();
|
||
int firstRow = ca.getFirstRow();
|
||
int lastRow = ca.getLastRow();
|
||
|
||
if (row >= firstRow && row <= lastRow) {
|
||
|
||
if (column >= firstColumn && column <= lastColumn) {
|
||
Row fRow = sheet.getRow(firstRow);
|
||
Cell fCell = fRow.getCell(firstColumn);
|
||
return getValue(fCell);
|
||
}
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* 判断指定的单元格是否是合并单元格
|
||
*
|
||
* @param sheet 工作表
|
||
* @param row 行下标
|
||
* @param column 列下标
|
||
* @return
|
||
*/
|
||
private static boolean isMergedRegion(Sheet sheet, int row, int column) {
|
||
int sheetMergeCount = sheet.getNumMergedRegions();
|
||
for (int i = 0; i < sheetMergeCount; i++) {
|
||
CellRangeAddress range = sheet.getMergedRegion(i);
|
||
int firstColumn = range.getFirstColumn();
|
||
int lastColumn = range.getLastColumn();
|
||
int firstRow = range.getFirstRow();
|
||
int lastRow = range.getLastRow();
|
||
if (row >= firstRow && row <= lastRow) {
|
||
if (column >= firstColumn && column <= lastColumn) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
public static String getValue(Cell hssfCell) {
|
||
if (hssfCell.getCellTypeEnum() == CellType.BOOLEAN) {
|
||
return String.valueOf(hssfCell.getBooleanCellValue());
|
||
} else if (hssfCell.getCellTypeEnum() == CellType.NUMERIC) {
|
||
//if (HSSFDateUtil.isCellDateFormatted(hssfCell)) {
|
||
if (CellDateUtil.isCellDateFormatted(hssfCell)) {
|
||
Date date = hssfCell.getDateCellValue();
|
||
return DateFormatUtils.format(date, "yyyy-MM-dd HH:mm:ss");
|
||
} else {
|
||
hssfCell.setCellType(CellType.STRING);
|
||
return String.valueOf(hssfCell.getStringCellValue());
|
||
}
|
||
} else if (hssfCell.getCellTypeEnum() == CellType.STRING) {
|
||
return String.valueOf(hssfCell.getStringCellValue());
|
||
} else {
|
||
hssfCell.setCellType(CellType.STRING);
|
||
return String.valueOf(hssfCell.getStringCellValue());
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取合并单元格的值
|
||
*
|
||
* @param sheet
|
||
* @param cell
|
||
* @return
|
||
*/
|
||
public static String getCellValue(Sheet sheet, Cell cell) {
|
||
String value = "";
|
||
if (cell != null) {
|
||
//log.info("-----------row:" +cell.getRowIndex()+"-------column:"+cell.getColumnIndex());
|
||
int row = cell.getRowIndex();
|
||
int column = cell.getColumnIndex();
|
||
boolean temp = isMergedRegion(sheet, row, column);
|
||
|
||
if (temp) {
|
||
value = getMergedRegionValue(sheet, row, column);
|
||
} else {
|
||
value = getValue(cell);
|
||
}
|
||
}
|
||
return value;
|
||
}
|
||
|
||
public static void exportAttendanceExcel(HttpServletResponse response) {
|
||
try {
|
||
ClassPathResource classPathResource = new ClassPathResource("excel/人员考勤导入模板.xlsx");
|
||
InputStream inputStream = classPathResource.getInputStream();
|
||
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
|
||
downLoadExcel("人员考勤导入模板.xlsx", response, workbook);
|
||
} catch (IOException e) {
|
||
log.error("error:", e);
|
||
}
|
||
}
|
||
|
||
public static void exportHiddenDangerLibraryExcel(HttpServletResponse response) {
|
||
try {
|
||
ClassPathResource classPathResource = new ClassPathResource("excel/安全隐患库_导入模板.xlsx");
|
||
InputStream inputStream = classPathResource.getInputStream();
|
||
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
|
||
downLoadExcel("安全隐患库_导入模板.xlsx", response, workbook);
|
||
} catch (IOException e) {
|
||
log.error("error:", e);
|
||
}
|
||
}
|
||
|
||
public static void exportInspectTableLibraryExcel(HttpServletResponse response) {
|
||
try {
|
||
ClassPathResource classPathResource = new ClassPathResource("excel/检查表导入模板.xlsx");
|
||
InputStream inputStream = classPathResource.getInputStream();
|
||
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
|
||
downLoadExcel("检查表导入模板.xlsx", response, workbook);
|
||
} catch (IOException e) {
|
||
log.error("error:", e);
|
||
}
|
||
}
|
||
|
||
public static void exporExcelWorkerTemplate(HttpServletResponse response, List<EntityMap> teamList, List<EntityMap> departmentList) {
|
||
try {
|
||
XSSFWorkbook workbook = getExcelWorkerTemplateWorkbook(teamList, departmentList);
|
||
downLoadExcel("人员导入模板.xlsx", response, workbook);
|
||
} catch (IOException e) {
|
||
log.error("error:", e);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取下载人员导入模板workbook
|
||
*
|
||
* @param teamList
|
||
* @param departmentList
|
||
* @return
|
||
* @throws IOException
|
||
*/
|
||
public static XSSFWorkbook getExcelWorkerTemplateWorkbook(List<EntityMap> teamList, List<EntityMap> departmentList) throws IOException {
|
||
ClassPathResource classPathResource = new ClassPathResource("excel/人员导入模板.xlsx");
|
||
InputStream inputStream = classPathResource.getInputStream();
|
||
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
|
||
//部门/班组下拉列
|
||
XSSFSheet sheet2 = workbook.getSheet("部门");
|
||
if (teamList.size() > 0) {
|
||
for (int i = 0; i < teamList.size(); i++) {
|
||
XSSFRow row1 = sheet2.createRow(i);
|
||
XSSFCell cell1 = row1.createCell(0);
|
||
cell1.setCellType(CellType.STRING);
|
||
cell1.setCellValue(MapUtils.getString(teamList.get(i), "enterpriseTeamName"));
|
||
}
|
||
}
|
||
if (departmentList.size() > 0) {
|
||
for (int i = 0; i < departmentList.size(); i++) {
|
||
XSSFRow row1 = sheet2.createRow(i + teamList.size());
|
||
XSSFCell cell1 = row1.createCell(0);
|
||
cell1.setCellType(CellType.STRING);
|
||
cell1.setCellValue(MapUtils.getString(departmentList.get(i), "enterpriseDepartmentName"));
|
||
}
|
||
}
|
||
return workbook;
|
||
}
|
||
|
||
public static void exporExcelSafeDevTemplate(HttpServletResponse response, List<SafetyHatFence> fenceList, List<EnterpriseInfo> enterpriseInfoList) {
|
||
try {
|
||
ClassPathResource classPathResource = new ClassPathResource("excel/安全帽设备导入模板.xlsx");
|
||
InputStream inputStream = classPathResource.getInputStream();
|
||
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
|
||
//围栏下拉列
|
||
XSSFSheet sheet2 = workbook.getSheet("围栏");
|
||
if (fenceList.size() > 0) {
|
||
for (int i = 0; i < fenceList.size(); i++) {
|
||
XSSFRow row1 = sheet2.createRow(i);
|
||
XSSFCell cell1 = row1.createCell(0);
|
||
cell1.setCellType(CellType.STRING);
|
||
cell1.setCellValue(fenceList.get(i).getFenceName());
|
||
}
|
||
}
|
||
//分包单位下拉列
|
||
XSSFSheet sheet3 = workbook.getSheet("分包单位");
|
||
if (enterpriseInfoList.size() > 0) {
|
||
for (int i = 0; i < enterpriseInfoList.size(); i++) {
|
||
XSSFRow row1 = sheet3.createRow(i);
|
||
XSSFCell cell1 = row1.createCell(0);
|
||
cell1.setCellType(CellType.STRING);
|
||
cell1.setCellValue(enterpriseInfoList.get(i).getEnterpriseName());
|
||
}
|
||
}
|
||
downLoadExcel("安全帽设备导入模板.xlsx", response, workbook);
|
||
} catch (IOException e) {
|
||
log.error("error:", e);
|
||
}
|
||
}
|
||
|
||
public static void exporExcelWorkerEducation(HttpServletResponse response, Map<String, Object> map, WorkerSafeEducationWorker workerSafeEducationWorker, WorkerType workerType, String basePath) {
|
||
try {
|
||
ClassPathResource classPathResource = new ClassPathResource("excel/工人教育档案.xlsx");
|
||
InputStream inputStream = classPathResource.getInputStream();
|
||
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
|
||
XSSFSheet sheet = workbook.getSheet("教育档案");
|
||
map.put("sex", MapUtils.getIntValue(map, "sex") == 1 ? "男" : "女");
|
||
Map<String, Object> placeholderMap = new HashMap<>(16);
|
||
for (String s : map.keySet()) {
|
||
placeholderMap.put("${" + s + "}", map.get(s));
|
||
}
|
||
placeholderMap.put("${studyTime}", workerSafeEducationWorker.getStudyTime());
|
||
placeholderMap.put("${score}", workerSafeEducationWorker.getScore());
|
||
placeholderMap.put("${workerTypeName}", workerType.getTypeName());
|
||
// 替换占位符
|
||
for (Row row : sheet) {
|
||
for (Cell cell : row) {
|
||
if (cell.getCellType() == CellType.STRING) {
|
||
String cellValue = cell.getStringCellValue();
|
||
for (String placeholder : placeholderMap.keySet()) {
|
||
if (cellValue.contains(placeholder)) {
|
||
cellValue = cellValue.replace(placeholder, placeholderMap.get(placeholder).toString());
|
||
cell.setCellValue(cellValue);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
String idCardBigPhotoUrl = MapUtils.getString(map, "idCardBigPhotoUrl");
|
||
if (StringUtils.isNotBlank(idCardBigPhotoUrl)) {
|
||
picture(basePath + idCardBigPhotoUrl, sheet, 9, 15, 13, 15);
|
||
}
|
||
String idCardUpPhotoUrl = MapUtils.getString(map, "idCardUpPhotoUrl");
|
||
if (StringUtils.isNotBlank(idCardBigPhotoUrl)) {
|
||
picture(basePath + idCardUpPhotoUrl, sheet, 20, 28, 1, 7);
|
||
}
|
||
String idCardDownPhotoUrl = MapUtils.getString(map, "idCardDownPhotoUrl");
|
||
if (StringUtils.isNotBlank(idCardDownPhotoUrl)) {
|
||
picture(basePath + idCardDownPhotoUrl, sheet, 20, 28, 9, 15);
|
||
}
|
||
downLoadExcel("工人教育档案.xlsx", response, workbook);
|
||
} catch (IOException e) {
|
||
log.error("error:", e);
|
||
}
|
||
}
|
||
|
||
private static void picture(String path, XSSFSheet sheet, int startRow, int endRow, int startCol, int endCol) {
|
||
try {
|
||
InputStream inputStreamPic = new FileInputStream(path);
|
||
byte[] imageBytes = IOUtils.toByteArray(inputStreamPic);
|
||
Drawing<?> drawing = sheet.createDrawingPatriarch();//用于在工作表上创建绘图对象
|
||
// 将图片插入单元格
|
||
int pictureIdx = sheet.getWorkbook().addPicture(imageBytes, Workbook.PICTURE_TYPE_JPEG);
|
||
CreationHelper helper = sheet.getWorkbook().getCreationHelper();
|
||
ClientAnchor anchor = helper.createClientAnchor();//用于指定图片的位置
|
||
anchor.setCol1(startCol);//指定其实位置
|
||
anchor.setRow1(startRow);
|
||
anchor.setCol2(endCol);//指定结束位置
|
||
anchor.setRow2(endRow);
|
||
drawing.createPicture(anchor, pictureIdx);//用于创建图片对象
|
||
} catch (IOException e) {
|
||
log.error("error:", e);
|
||
}
|
||
}
|
||
|
||
public static void exporExcelExamQuestionBankTemplate(HttpServletResponse response, List<ExamSubject> subjectList) {
|
||
try {
|
||
ClassPathResource classPathResource = new ClassPathResource("excel/题库导入模版.xlsx");
|
||
InputStream inputStream = classPathResource.getInputStream();
|
||
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
|
||
//部门/班组下拉列
|
||
XSSFSheet sheet2 = workbook.getSheet("科目名称");
|
||
if (subjectList.size() > 0) {
|
||
for (int i = 0; i < subjectList.size(); i++) {
|
||
XSSFRow row1 = sheet2.createRow(i);
|
||
XSSFCell cell1 = row1.createCell(0);
|
||
cell1.setCellType(CellType.STRING);
|
||
cell1.setCellValue(subjectList.get(i).getName());
|
||
}
|
||
}
|
||
downLoadExcel("题库导入模版.xlsx", response, workbook);
|
||
} catch (IOException e) {
|
||
log.error("error:", e);
|
||
}
|
||
}
|
||
|
||
public static void exporWorkerAttendByHw(HttpServletResponse response, List<WorkerAttendanceDto> pageList, String basePath) {
|
||
try {
|
||
ClassPathResource classPathResource = new ClassPathResource("excel/班前教育信息.xlsx");
|
||
InputStream inputStream = classPathResource.getInputStream();
|
||
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
|
||
XSSFSheet sheet = workbook.getSheet("班前教育");
|
||
for (int i = 2; i < pageList.size() + 2; i++) {
|
||
for (int j = 0; j < 12; j++) {
|
||
if (j == 0) {
|
||
sheet.getRow(i).getCell(j).setCellValue(i - 1);
|
||
}
|
||
if (j == 1) {
|
||
sheet.getRow(i).getCell(j).setCellValue(pageList.get(i - 2).getWorkerName());
|
||
}
|
||
if (j == 2) {
|
||
sheet.getRow(i).getCell(j).setCellValue(pageList.get(i - 2).getSexName());
|
||
}
|
||
if (j == 3) {
|
||
sheet.getRow(i).getCell(j).setCellValue(pageList.get(i - 2).getAge());
|
||
}
|
||
if (j == 4) {
|
||
sheet.getRow(i).getCell(j).setCellValue(pageList.get(i - 2).getEnterpriseName());
|
||
}
|
||
if (j == 5) {
|
||
if (StringUtils.isNotBlank(pageList.get(i - 2).getImageUrl())) {
|
||
String imageUrl = pageList.get(i - 2).getImageUrl();
|
||
picture(basePath + imageUrl, sheet, i, i + 1, j, j + 1);
|
||
}
|
||
}
|
||
if (j == 6) {
|
||
sheet.getRow(i).getCell(j).setCellValue(pageList.get(i - 2).getCreateTime());
|
||
}
|
||
}
|
||
}
|
||
downLoadExcel("班前教育信息.xlsx", response, workbook);
|
||
} catch (IOException e) {
|
||
log.error("error:", e);
|
||
}
|
||
}
|
||
|
||
public static void exportExcelCarTemplate(List<EnterpriseInfo> enterpriseInfos, List<CarType> carTypes, File file) {
|
||
try {
|
||
ClassPathResource classPathResource = new ClassPathResource("excel/车辆导入模板.xlsx");
|
||
InputStream inputStream = classPathResource.getInputStream();
|
||
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
|
||
//单位
|
||
XSSFSheet sheet1 = workbook.getSheet("单位");
|
||
if (enterpriseInfos.size() > 0) {
|
||
for (int i = 0; i < enterpriseInfos.size(); i++) {
|
||
XSSFRow row1 = sheet1.createRow(i);
|
||
XSSFCell cell1 = row1.createCell(0);
|
||
EnterpriseInfo obj = enterpriseInfos.get(i);
|
||
cell1.setCellType(CellType.STRING);
|
||
cell1.setCellValue(obj.getEnterpriseName());
|
||
}
|
||
}
|
||
|
||
//车种类型
|
||
XSSFSheet sheet2 = workbook.getSheet("车种类型");
|
||
if (carTypes.size() > 0) {
|
||
for (int i = 0; i < carTypes.size(); i++) {
|
||
XSSFRow row1 = sheet2.createRow(i);
|
||
XSSFCell cell1 = row1.createCell(0);
|
||
CarType obj = carTypes.get(i);
|
||
cell1.setCellType(CellType.STRING);
|
||
cell1.setCellValue(obj.getCarTypeName());
|
||
}
|
||
}
|
||
|
||
workbook.write(new FileOutputStream(file));
|
||
// downLoadExcel("车辆导入模板.xlsx", response, workbook);
|
||
} catch (IOException e) {
|
||
log.error("error:", e);
|
||
}
|
||
}
|
||
|
||
|
||
/*public static void main(String[] args) {
|
||
try {
|
||
InputStream instream = new FileInputStream("D:/qqq.xlsx");
|
||
XSSFWorkbook workbook = new XSSFWorkbook(instream);
|
||
XSSFSheet sheet = workbook.getSheetAt(0);
|
||
XSSFCell cell=sheet.getRow(0).getCell(1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
|
||
log.info("项目:"+cell.getStringCellValue());
|
||
XSSFCell cell2=sheet.getRow(3).getCell(8, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
|
||
log.info("评估时间:"+getValue(cell2));
|
||
XSSFCell cell3=sheet.getRow(10).getCell(10, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
|
||
log.info("实测实量得分:"+getValue(cell3));
|
||
XSSFCell cell4=sheet.getRow(14).getCell(10, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
|
||
log.info("质量风险得分:"+getValue(cell4));
|
||
XSSFCell cell5=sheet.getRow(23).getCell(10, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
|
||
log.info("安全文明得分:"+getValue(cell5));
|
||
XSSFCell cell6=sheet.getRow(32).getCell(2, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
|
||
log.info("标段评估结果:"+getValue(cell6));
|
||
workbook.close();
|
||
instream.close();
|
||
} catch (Exception e) {
|
||
log.error("error:",e);
|
||
}
|
||
}*/
|
||
|
||
/**
|
||
* 删除excel的列
|
||
*
|
||
* @param workbook
|
||
* @param sheetIndex
|
||
* @param deleteColumnIndexes
|
||
* @throws IOException
|
||
*/
|
||
public static void removeColumns(Workbook workbook, int sheetIndex, List<Integer> deleteColumnIndexes) throws IOException {
|
||
// 对列索引进行降序排序,以便从右到左删除,避免索引变化问题
|
||
deleteColumnIndexes.sort(Collections.reverseOrder());
|
||
|
||
Sheet sheet = workbook.getSheetAt(sheetIndex);
|
||
for (int colIndex : deleteColumnIndexes) {
|
||
removeColumn(sheet, colIndex);
|
||
}
|
||
}
|
||
|
||
public static void removeColumns(String excelPath, int sheetIndex, List<Integer> columnIndexes) throws IOException {
|
||
// 对列索引进行降序排序,以便从右到左删除,避免索引变化问题
|
||
columnIndexes.sort(Collections.reverseOrder());
|
||
|
||
try (FileInputStream fis = new FileInputStream(excelPath);
|
||
Workbook workbook = WorkbookFactory.create(fis)) {
|
||
|
||
Sheet sheet = workbook.getSheetAt(sheetIndex);
|
||
|
||
for (int colIndex : columnIndexes) {
|
||
removeColumn(sheet, colIndex);
|
||
}
|
||
|
||
try (FileOutputStream fos = new FileOutputStream(excelPath)) {
|
||
workbook.write(fos);
|
||
}
|
||
}
|
||
}
|
||
|
||
private static void removeColumn(Sheet sheet, int colIndex) {
|
||
// 处理行数据
|
||
for (int rowIndex = 0; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
|
||
Row row = sheet.getRow(rowIndex);
|
||
if (row != null) {
|
||
removeCell(row, colIndex);
|
||
|
||
// 将右侧单元格左移
|
||
shiftCellsLeft(row, colIndex);
|
||
}
|
||
}
|
||
|
||
// 处理合并区域
|
||
processMergedRegions(sheet, colIndex);
|
||
|
||
// 处理列宽
|
||
shiftColumnWidths(sheet, colIndex);
|
||
}
|
||
|
||
private static void removeCell(Row row, int colIndex) {
|
||
Cell cell = row.getCell(colIndex);
|
||
if (cell != null) {
|
||
row.removeCell(cell);
|
||
}
|
||
}
|
||
|
||
private static void shiftCellsLeft(Row row, int colIndex) {
|
||
for (int i = colIndex + 1; i <= row.getLastCellNum(); i++) {
|
||
Cell oldCell = row.getCell(i);
|
||
if (oldCell != null) {
|
||
Cell newCell = row.createCell(i - 1, oldCell.getCellType());
|
||
copyCellContent(oldCell, newCell);
|
||
copyCellStyle(oldCell, newCell);
|
||
row.removeCell(oldCell);
|
||
}
|
||
}
|
||
}
|
||
|
||
private static void copyCellContent(Cell oldCell, Cell newCell) {
|
||
switch (oldCell.getCellType()) {
|
||
case STRING:
|
||
newCell.setCellValue(oldCell.getStringCellValue());
|
||
break;
|
||
case NUMERIC:
|
||
newCell.setCellValue(oldCell.getNumericCellValue());
|
||
break;
|
||
case BOOLEAN:
|
||
newCell.setCellValue(oldCell.getBooleanCellValue());
|
||
break;
|
||
case FORMULA:
|
||
newCell.setCellFormula(oldCell.getCellFormula());
|
||
break;
|
||
case BLANK:
|
||
newCell.setCellValue(""); // 将单元格值设置为空字符串
|
||
newCell.setCellType(CellType.BLANK);
|
||
break;
|
||
case ERROR:
|
||
newCell.setCellErrorValue(oldCell.getErrorCellValue());
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
private static void copyCellStyle(Cell oldCell, Cell newCell) {
|
||
Workbook workbook = newCell.getSheet().getWorkbook();
|
||
CellStyle newStyle = workbook.createCellStyle();
|
||
newStyle.cloneStyleFrom(oldCell.getCellStyle());
|
||
newCell.setCellStyle(newStyle);
|
||
}
|
||
|
||
private static void processMergedRegions(Sheet sheet, int colIndex) {
|
||
for (int i = sheet.getNumMergedRegions() - 1; i >= 0; i--) {
|
||
CellRangeAddress region = sheet.getMergedRegion(i);
|
||
|
||
if (colIndex >= region.getFirstColumn() && colIndex <= region.getLastColumn()) {
|
||
// 如果删除的列在合并区域内
|
||
if (region.getFirstColumn() == region.getLastColumn()) {
|
||
// 如果合并区域只有一列,直接删除
|
||
sheet.removeMergedRegion(i);
|
||
} else {
|
||
// 缩小合并区域
|
||
region.setLastColumn(region.getLastColumn() - 1);
|
||
sheet.removeMergedRegion(i);
|
||
sheet.addMergedRegion(region);
|
||
}
|
||
} else if (colIndex < region.getFirstColumn()) {
|
||
// 如果删除的列在合并区域左侧,将合并区域左移
|
||
region.setFirstColumn(region.getFirstColumn() - 1);
|
||
region.setLastColumn(region.getLastColumn() - 1);
|
||
sheet.removeMergedRegion(i);
|
||
sheet.addMergedRegion(region);
|
||
}
|
||
// 如果删除的列在合并区域右侧,不需要处理
|
||
}
|
||
}
|
||
|
||
private static void shiftColumnWidths(Sheet sheet, int colIndex) {
|
||
int maxColumn = 255; // Excel的最大列数
|
||
for (int i = colIndex; i < maxColumn; i++) {
|
||
int width = sheet.getColumnWidth(i + 1);
|
||
sheet.setColumnWidth(i, width);
|
||
}
|
||
// 清空最后一列
|
||
sheet.setColumnWidth(maxColumn, sheet.getDefaultColumnWidth());
|
||
}
|
||
|
||
// 示例用法
|
||
public static void main(String[] args) {
|
||
try {
|
||
// 假设要删除第1列和第3列(0-based索引)
|
||
long l = System.currentTimeMillis();
|
||
List<Integer> columnsToRemove = new ArrayList<>();
|
||
for (int i = 13; i < 41 + 1; i++) {
|
||
columnsToRemove.add(i);
|
||
}
|
||
removeColumns("C:\\Users\\Administrator\\Desktop\\1.xlsx", 0, columnsToRemove);
|
||
System.out.println("列删除成功!" + (System.currentTimeMillis() - l));
|
||
} catch (IOException e) {
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 合并Excel中的行
|
||
*
|
||
* @param filePath Excel文件路径
|
||
* @param sheetIndex 工作表索引(0-based)
|
||
* @param startRow 开始行索引(0-based)
|
||
* @param endRow 结束行索引(0-based)
|
||
* @throws IOException 文件操作异常
|
||
*/
|
||
public static void mergeRows(String filePath, int sheetIndex, int startRow, int endRow) throws IOException {
|
||
if (startRow > endRow) {
|
||
throw new IllegalArgumentException("开始行索引不能大于结束行索引");
|
||
}
|
||
|
||
try (FileInputStream fis = new FileInputStream(filePath);
|
||
Workbook workbook = WorkbookFactory.create(fis)) {
|
||
|
||
Sheet sheet = workbook.getSheetAt(sheetIndex);
|
||
|
||
// 获取工作表的列数
|
||
int lastColumn = getLastColumn(sheet, startRow, endRow);
|
||
|
||
// 逐列合并行
|
||
for (int colIndex = 0; colIndex <= lastColumn; colIndex++) {
|
||
mergeCellsInColumn(sheet, colIndex, startRow, endRow);
|
||
}
|
||
|
||
// 保存修改后的文件
|
||
try (FileOutputStream fos = new FileOutputStream(filePath)) {
|
||
workbook.write(fos);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取工作表中指定行范围内的最大列数
|
||
*/
|
||
private static int getLastColumn(Sheet sheet, int startRow, int endRow) {
|
||
int maxColumn = -1;
|
||
for (int rowIndex = startRow; rowIndex <= endRow; rowIndex++) {
|
||
Row row = sheet.getRow(rowIndex);
|
||
if (row != null) {
|
||
int lastCellNum = row.getLastCellNum();
|
||
if (lastCellNum > maxColumn) {
|
||
maxColumn = lastCellNum;
|
||
}
|
||
}
|
||
}
|
||
return maxColumn == -1 ? 0 : maxColumn - 1;
|
||
}
|
||
|
||
/**
|
||
* 合并指定列中的行单元格
|
||
*/
|
||
private static void mergeCellsInColumn(Sheet sheet, int colIndex, int startRow, int endRow) {
|
||
// 检查是否需要合并(检查单元格内容是否相同)
|
||
if (shouldMergeCells(sheet, colIndex, startRow, endRow)) {
|
||
// 创建合并区域
|
||
CellRangeAddress mergeRegion = new CellRangeAddress(
|
||
startRow, // 起始行
|
||
endRow, // 结束行
|
||
colIndex, // 起始列
|
||
colIndex // 结束列
|
||
);
|
||
|
||
// 添加合并区域到工作表
|
||
sheet.addMergedRegion(mergeRegion);
|
||
|
||
// 设置合并后单元格的样式和内容
|
||
setMergedCellContentAndStyle(sheet, colIndex, startRow, endRow);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 检查指定列中的单元格内容是否相同(决定是否需要合并)
|
||
*/
|
||
private static boolean shouldMergeCells(Sheet sheet, int colIndex, int startRow, int endRow) {
|
||
if (startRow == endRow) {
|
||
return false; // 只有一行,不需要合并
|
||
}
|
||
|
||
Object firstValue = null;
|
||
for (int rowIndex = startRow; rowIndex <= endRow; rowIndex++) {
|
||
Row row = sheet.getRow(rowIndex);
|
||
if (row == null) {
|
||
return false; // 有空行,不合并
|
||
}
|
||
|
||
Cell cell = row.getCell(colIndex);
|
||
Object currentValue = getCellValue(cell);
|
||
|
||
if (firstValue == null) {
|
||
firstValue = currentValue;
|
||
} else if (!isEqual(firstValue, currentValue)) {
|
||
return false; // 值不相同,不合并
|
||
}
|
||
}
|
||
|
||
return firstValue != null; // 所有值相同且不为空,可以合并
|
||
}
|
||
|
||
/**
|
||
* 获取单元格的值
|
||
*/
|
||
private static Object getCellValue(Cell cell) {
|
||
if (cell == null) {
|
||
return null;
|
||
}
|
||
|
||
switch (cell.getCellType()) {
|
||
case STRING:
|
||
return cell.getStringCellValue();
|
||
case NUMERIC:
|
||
return cell.getNumericCellValue();
|
||
case BOOLEAN:
|
||
return cell.getBooleanCellValue();
|
||
case FORMULA:
|
||
return cell.getCellFormula();
|
||
case BLANK:
|
||
return "";
|
||
case ERROR:
|
||
return cell.getErrorCellValue();
|
||
default:
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 比较两个值是否相等
|
||
*/
|
||
private static boolean isEqual(Object value1, Object value2) {
|
||
if (value1 == null && value2 == null) {
|
||
return true;
|
||
}
|
||
if (value1 == null || value2 == null) {
|
||
return false;
|
||
}
|
||
return value1.equals(value2);
|
||
}
|
||
|
||
/**
|
||
* 设置合并后单元格的内容和样式
|
||
*/
|
||
private static void setMergedCellContentAndStyle(Sheet sheet, int colIndex, int startRow, int endRow) {
|
||
Row firstRow = sheet.getRow(startRow);
|
||
if (firstRow == null) {
|
||
firstRow = sheet.createRow(startRow);
|
||
}
|
||
|
||
Cell firstCell = firstRow.getCell(colIndex);
|
||
if (firstCell == null) {
|
||
firstCell = firstRow.createCell(colIndex);
|
||
}
|
||
|
||
// 设置合并区域的样式(使用第一个单元格的样式)
|
||
CellStyle style = firstCell.getCellStyle();
|
||
|
||
// 为合并区域内的所有单元格设置相同的样式
|
||
for (int rowIndex = startRow; rowIndex <= endRow; rowIndex++) {
|
||
Row row = sheet.getRow(rowIndex);
|
||
if (row == null) {
|
||
row = sheet.createRow(rowIndex);
|
||
}
|
||
|
||
Cell cell = row.getCell(colIndex);
|
||
if (cell == null) {
|
||
cell = row.createCell(colIndex);
|
||
}
|
||
|
||
cell.setCellStyle(style);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 重载方法:合并指定区域
|
||
*/
|
||
public static void mergeRows(Workbook workbook, int sheetIndex, int startRow, int endRow, int startCol, int endCol) throws IOException {
|
||
Sheet sheet = workbook.getSheetAt(sheetIndex);
|
||
// 创建合并区域
|
||
CellRangeAddress mergeRegion = new CellRangeAddress(
|
||
startRow, endRow, startCol, endCol
|
||
);
|
||
// 添加合并区域
|
||
sheet.addMergedRegion(mergeRegion);
|
||
|
||
// 设置合并区域样式
|
||
setMergedRegionStyle(sheet, mergeRegion);
|
||
}
|
||
|
||
/**
|
||
* 设置合并区域的样式
|
||
*/
|
||
private static void setMergedRegionStyle(Sheet sheet, CellRangeAddress region) {
|
||
Row firstRow = sheet.getRow(region.getFirstRow());
|
||
if (firstRow == null) {
|
||
firstRow = sheet.createRow(region.getFirstRow());
|
||
}
|
||
|
||
Cell firstCell = firstRow.getCell(region.getFirstColumn());
|
||
if (firstCell == null) {
|
||
firstCell = firstRow.createCell(region.getFirstColumn());
|
||
}
|
||
|
||
CellStyle style = firstCell.getCellStyle();
|
||
|
||
// 为合并区域内的所有单元格设置相同样式
|
||
for (int row = region.getFirstRow(); row <= region.getLastRow(); row++) {
|
||
Row currentRow = sheet.getRow(row);
|
||
if (currentRow == null) {
|
||
currentRow = sheet.createRow(row);
|
||
}
|
||
|
||
for (int col = region.getFirstColumn(); col <= region.getLastColumn(); col++) {
|
||
Cell cell = currentRow.getCell(col);
|
||
if (cell == null) {
|
||
cell = currentRow.createCell(col);
|
||
}
|
||
cell.setCellStyle(style);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 导出图片到excel
|
||
*
|
||
* @param workbook 工作簿
|
||
* @param sheetIndex 工作表索引
|
||
* @param bytesList 导出的图片字节数组列表
|
||
* @param startRow 开始行
|
||
* @param startCol 开始列
|
||
* @param direction 方向:1纵向2横向
|
||
*/
|
||
public static void exportPicture(Workbook workbook, int sheetIndex, List<byte[]> bytesList,
|
||
int startRow, int startCol, int direction) {
|
||
if (workbook == null || bytesList == null || bytesList.isEmpty()) {
|
||
return;
|
||
}
|
||
|
||
Sheet sheet = workbook.getSheetAt(sheetIndex);
|
||
if (sheet == null) {
|
||
return;
|
||
}
|
||
|
||
Drawing<?> drawing = sheet.createDrawingPatriarch();
|
||
int rowIndex = startRow;
|
||
int colIndex = startCol;
|
||
|
||
for (byte[] bytes : bytesList) {
|
||
if (bytes == null || bytes.length == 0) {
|
||
continue;
|
||
}
|
||
|
||
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) {
|
||
// 获取图片格式(简单判断,实际可能需要更复杂的检测)
|
||
int pictureType = getPictureType(bytes);
|
||
|
||
// 添加图片到工作簿
|
||
int pictureIndex = workbook.addPicture(bytes, pictureType);
|
||
|
||
// 创建锚点定位图片
|
||
ClientAnchor anchor;
|
||
if (workbook instanceof XSSFWorkbook) {
|
||
anchor = new XSSFClientAnchor();
|
||
} else if (workbook instanceof HSSFWorkbook) {
|
||
anchor = new HSSFClientAnchor();
|
||
} else {
|
||
anchor = workbook.getCreationHelper().createClientAnchor();
|
||
}
|
||
|
||
// 设置图片位置
|
||
anchor.setCol1(colIndex);
|
||
anchor.setRow1(rowIndex);
|
||
anchor.setCol2(colIndex + 1); // 默认占1列宽度
|
||
anchor.setRow2(rowIndex + 1); // 默认占1行高度
|
||
|
||
// 插入图片
|
||
drawing.createPicture(anchor, pictureIndex);
|
||
|
||
// 根据方向调整下一个图片的位置
|
||
if (direction == 1) {
|
||
// 纵向排列:向下移动一行
|
||
rowIndex++;
|
||
} else {
|
||
// 横向排列:向右移动一列
|
||
colIndex++;
|
||
}
|
||
|
||
} catch (Exception e) {
|
||
log.error("", e);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 根据图片字节数组判断图片类型
|
||
*/
|
||
private static int getPictureType(byte[] bytes) {
|
||
if (bytes.length < 4) {
|
||
return Workbook.PICTURE_TYPE_PNG;
|
||
}
|
||
|
||
// 检查文件头标识
|
||
if (bytes[0] == (byte) 0xFF && bytes[1] == (byte) 0xD8) {
|
||
return Workbook.PICTURE_TYPE_JPEG;
|
||
} else if (bytes[0] == (byte) 0x89 && bytes[1] == (byte) 0x50 &&
|
||
bytes[2] == (byte) 0x4E && bytes[3] == (byte) 0x47) {
|
||
return Workbook.PICTURE_TYPE_PNG;
|
||
} else if (bytes[0] == (byte) 0x42 && bytes[1] == (byte) 0x4D) {
|
||
return Workbook.PICTURE_TYPE_DIB;
|
||
} else if (bytes[0] == (byte) 0x00 && bytes[1] == (byte) 0x00 &&
|
||
bytes[2] == (byte) 0x01 && bytes[3] == (byte) 0x00) {
|
||
return Workbook.PICTURE_TYPE_EMF;
|
||
} else if (bytes[0] == (byte) 0x00 && bytes[1] == (byte) 0x00 &&
|
||
bytes[2] == (byte) 0x02 && bytes[3] == (byte) 0x00) {
|
||
return Workbook.PICTURE_TYPE_WMF;
|
||
}
|
||
|
||
// 默认返回PNG类型
|
||
return Workbook.PICTURE_TYPE_PNG;
|
||
}
|
||
|
||
// // 示例用法
|
||
// public static void main(String[] args) {
|
||
// try {
|
||
// // 示例1:合并第2行到第5行的所有列(0-based索引)
|
||
// mergeRows("C:\\Users\\Administrator\\Desktop\\heng.xlsx", 0, 0, 7);
|
||
//
|
||
// // 示例2:合并第3行到第6行的第2列(0-based索引)
|
||
//// mergeRows("example.xlsx", 0, 2, 5, 1, 1);
|
||
//
|
||
// System.out.println("行合并成功!");
|
||
// } catch (IOException e) {
|
||
// e.printStackTrace();
|
||
// }
|
||
//}
|
||
|
||
}
|