最近做的项目导入的数据量比较大,直接用poi或者easypoi会可能会出现OOM的情况,综合考虑下用easyexcel,

pom引入所需包

        <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>1.1.2-beta5</version></dependency>

excelUtil.java

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.CollectionUtils;
import com.cmbchina.ccd.oa.socialsecurity.model.bo.ExcelListener;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** @description: excel工具类* @author: kongwc* @create: 2019-09-23*/
@Component
public class ExcelUtil {private static Sheet initSheet;static {initSheet = new Sheet(1, 0);initSheet.setSheetName("sheet");//设置自适应宽度initSheet.setAutoWidth(Boolean.TRUE);}/*** 读取少于1000行数据* 数据量少时,同步读取** @param file 读取的文件* @return*/public List<Object> readLessThan1000Row(MultipartFile file) throws IOException {return readLessThan1000RowBySheet(file, null);}/*** 读小于1000行数据* filePath 文件绝对路径* initSheet :* sheetNo: sheet页码,默认为1* headLineMun: 从第几行开始读取数据,默认为0, 表示从第一行开始读取* clazz: 返回数据List<Object> 中Object的类名*/public List<Object> readLessThan1000RowBySheet(MultipartFile file, Sheet sheet) throws IOException {if (file == null) {//log.info("导入文件为空", file);return null;}sheet = sheet != null ? sheet : initSheet;InputStream fileStream = null;try {fileStream = file.getInputStream();return EasyExcelFactory.read(fileStream, sheet);} catch (FileNotFoundException e) {//log.info("文件有误, 文件:{}", file);} finally {try {if (fileStream != null) {fileStream.close();}} catch (IOException e) {//log.info("excel文件读取失败, 失败原因:{}", e);}}return null;}/*** 生成excle** @param filePath 绝对路径, 如:/home/Downloads/aaa.xlsx* @param data     数据源* @param head     表头*/public static void writeBySimple(String filePath, List<List<Object>> data, List<String> head) {writeSimpleBySheet(filePath, data, head, null);}/*** 生成excle** @param filePath 绝对路径* @param data     数据源* @param sheet    excle页面样式* @param head     表头*/public static void writeSimpleBySheet(String filePath, List<List<Object>> data, List<String> head, Sheet sheet) {sheet = (sheet != null) ? sheet : initSheet;if (head != null) {List<List<String>> list = new ArrayList<>();head.forEach(h -> list.add(Collections.singletonList(h)));sheet.setHead(list);}OutputStream outputStream = null;ExcelWriter writer = null;try {outputStream = new FileOutputStream(filePath);writer = EasyExcelFactory.getWriter(outputStream);writer.write1(data, sheet);} catch (FileNotFoundException e) {//log.error("找不到文件或文件路径错误, 文件:{}", filePath);} finally {try {if (writer != null) {writer.finish();}if (outputStream != null) {outputStream.close();}} catch (IOException e) {//log.error("excel文件导出失败");}}}/*** @Description 导出excel 支持一张表导出多个sheet* @Param OutputStream 输出流* Map<String, List>  sheetName和每个sheet的数据* ExcelTypeEnum 要导出的excel的类型 有ExcelTypeEnum.xls 和有ExcelTypeEnum.xlsx*/public void createExcel(HttpServletResponse response, Map<String, List<? extends BaseRowModel>> sheetNameAndDateList, ExcelTypeEnum type, String fileName) {// if (checkParam(SheetNameAndDateList, type)) return;try {response.setContentType("multipart/form-data");response.setCharacterEncoding("utf-8");//解决导出文件名中文乱码fileName = new String(fileName.getBytes(), "iso8859-1") + DateUtil.todayStr();response.setHeader("Content-disposition", "attachment;filename=" + fileName + type.getValue());ServletOutputStream out = response.getOutputStream();ExcelWriter writer = new ExcelWriter(out, type, true);setSheet(sheetNameAndDateList, writer);writer.finish();out.flush();} catch (IOException e) {e.printStackTrace();}}/*** @Description //setSheet数据*/private void setSheet(Map<String, List<? extends BaseRowModel>> SheetNameAndDateList, ExcelWriter writer) {int sheetNum = 1;for (Map.Entry<String, List<? extends BaseRowModel>> stringListEntry : SheetNameAndDateList.entrySet()) {Sheet sheet = new Sheet(sheetNum, 0, stringListEntry.getValue().get(0).getClass());sheet.setSheetName(stringListEntry.getKey());writer.write(stringListEntry.getValue(), sheet);sheetNum++;}}/*** @Description 校验参数*/private static boolean checkParam(Map<String, List<? extends BaseRowModel>> SheetNameAndDateList, ExcelTypeEnum type) {if (CollectionUtils.isEmpty(SheetNameAndDateList)) {//log.error("SheetNameAndDateList不能为空");return true;} else if (type == null) {//log.error("导出的excel类型不能为空");return true;}return false;}/*** 读取某个 sheet 的 Excel** @param excel    文件* @param rowModel 实体类映射,继承 BaseRowModel 类* @return Excel 数据 list*/public static List<Object> readExcel(MultipartFile excel, BaseRowModel rowModel) throws IOException {return readExcel(excel, rowModel, 1, 1);}/*** 读取某个 sheet 的 Excel** @param excel    文件* @param rowModel 实体类映射,继承 BaseRowModel 类* @param sheetNo  sheet 的序号 从1开始* @return Excel 数据 list*/public Map<String, Object> readExcel(MultipartFile excel, BaseRowModel rowModel, int sheetNo) throws IOException {Map<String, Object> result = new HashMap<>();ExcelListener excelListener = new ExcelListener();ExcelReader reader = getReader(excel, excelListener);if (reader == null) {return null;}reader.read(new Sheet(sheetNo, 0, rowModel.getClass()));//校验表头Boolean flag = false;//维护实体类中 没有@ExcelProperty 放置在最后,会被映射出null表头String head = excelListener.getImportHeads().replace("null,", "");if (head.equals(excelListener.getModelHeads())) {flag = true;}result.put("flag", flag);result.put("datas", excelListener.getDatas());return result;}/*** 读取某个 sheet 的 Excel** @param excel       文件* @param rowModel    实体类映射,继承 BaseRowModel 类* @param sheetNo     sheet 的序号 从1开始* @param headLineNum 表头行数,默认为1* @return Excel 数据 list*/public static List<Object> readExcel(MultipartFile excel, BaseRowModel rowModel, int sheetNo, int headLineNum) throws IOException {ExcelListener excelListener = new ExcelListener();ExcelReader reader = getReader(excel, excelListener);if (reader == null) {return null;}reader.read(new Sheet(sheetNo, headLineNum, rowModel.getClass()));return excelListener.getDatas();}/*** 读取指定sheetName的Excel(多个 sheet)** @param excel    文件* @param rowModel 实体类映射,继承 BaseRowModel 类* @return Excel 数据 list* @throws IOException*/public static List<Object> readExcel(MultipartFile excel, BaseRowModel rowModel, String sheetName) throws IOException {ExcelListener excelListener = new ExcelListener();ExcelReader reader = getReader(excel, excelListener);if (reader == null) {return null;}for (Sheet sheet : reader.getSheets()) {if (rowModel != null) {sheet.setClazz(rowModel.getClass());}//读取指定名称的sheetif (sheet.getSheetName().contains(sheetName)) {reader.read(sheet);break;}}return excelListener.getDatas();}/*** 返回 ExcelReader** @param excel         需要解析的 Excel 文件* @param excelListener new ExcelListener()* @throws IOException*/private static ExcelReader getReader(MultipartFile excel, ExcelListener excelListener) throws IOException {String filename = excel.getOriginalFilename();if (filename != null && (filename.toLowerCase().endsWith(".xls") || filename.toLowerCase().endsWith(".xlsx"))) {InputStream is = new BufferedInputStream(excel.getInputStream());return new ExcelReader(is, null, excelListener, false);} else {return null;}}
}

但是easyexcel导出的功能还不丰富,比如带下拉选择的时候,还是需要原生的poi才行,所以决定导入数据量大的时候用easyexcel,导出时就用poi导出,由于easyexcel已引入poi,所以如果引入poi的时候要注意版本一致

pom文件

<!--poi相关 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.17</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.17</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>3.17</version></dependency>

PoiExcelUtil.java

import com.alibaba.excel.util.StyleUtil;
import com.cmbchina.ccd.oa.socialsecurity.model.bo.excel.ColumnName;
import com.cmbchina.ccd.oa.socialsecurity.model.bo.excel.SelectData;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.message.BasicNameValuePair;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
import org.apache.poi.xssf.usermodel.XSSFDataValidationConstraint;
import org.apache.poi.xssf.usermodel.XSSFDataValidationHelper;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Component;import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;/*** Excel文件相关操作工具类** @author kongwc* @create 2018-05-09 18:23*/@Component
public class PoiExcelUtil<T> {private static final String EXCEL_TEMPLATE = "classpath:/fileTemplate/EmailNoticeExcelTemplate.xlsx";private static final String CANCEL_ORDER_EXCEL_TEMPLATE = "classpath:/fileTemplate/CancelOrder.xlsx";/*** 没有定义转换时间格式** @param clazz* @param stream* @return* @throws NoSuchFieldException* @throws InstantiationException* @throws IllegalAccessException* @throws ParseException* @throws IOException*/public List<T> excelToList(Class<T> clazz, InputStream stream)throws NoSuchFieldException, InstantiationException, IllegalAccessException, ParseException, IOException {return excelToListWithDateForMate(clazz, stream, null);}/*** 定义转换时间格式** @param clazz* @param stream* @param dateFormat* @return* @throws NoSuchFieldException* @throws InstantiationException* @throws IllegalAccessException* @throws ParseException* @throws IOException*/public List<T> excelToList(Class<T> clazz, InputStream stream, String dateFormat)throws NoSuchFieldException, InstantiationException, IllegalAccessException, ParseException, IOException {return excelToListWithDateForMate(clazz, stream, dateFormat);}/*** 将文件流转成列表** @param clazz  泛型类型* @param stream 文件流* @return 列表*/public List<T> excelToListWithDateForMate(Class<T> clazz, InputStream stream, String dateFormat)throws IOException, IllegalAccessException, InstantiationException, NoSuchFieldException, ParseException,ParseException {if (dateFormat == null) {dateFormat = "yyyy-MM-dd HH:mm:ss";}if (stream == null) {return new ArrayList<>();}XSSFSheet xssfSheet = new XSSFWorkbook(stream).getSheetAt(0);//开始、结束行号int rowStart = xssfSheet.getFirstRowNum();int rowEnd = xssfSheet.getLastRowNum();XSSFRow columnNames = xssfSheet.getRow(rowStart);//列的开始,结束int cellStart = columnNames.getFirstCellNum();int cellEnd = columnNames.getLastCellNum();List<BasicNameValuePair> columnValues = new ArrayList<>();Field[] fields = clazz.getDeclaredFields();for (int k = cellStart; k < cellEnd; k++) {for (Field fieldItem : fields) {ColumnName cn = fieldItem.getAnnotation(ColumnName.class);if (cn != null) {String columnChineseName = fieldItem.getAnnotation(ColumnName.class).value();if (columnNames.getCell(k).getStringCellValue().equals(columnChineseName)) {columnValues.add(new BasicNameValuePair(fieldItem.getName(),fieldItem.getGenericType().toString()));break;}}}//导入的列与实际列不一致if (columnValues.size() <= k - cellStart) {return null;}}List<T> result = new ArrayList<>();for (int i = rowStart + 1; i <= rowEnd; i++) {T t = clazz.newInstance();XSSFRow row = xssfSheet.getRow(i);//不为空行if (row != null) {for (int k = cellStart; k < cellEnd; k++) {XSSFCell cell = row.getCell(k);Field field = clazz.getDeclaredField(columnValues.get(k - cellStart).getName());field.setAccessible(true);switch (columnValues.get(k - cellStart).getValue()) {case "class java.lang.String":field.set(t, getCellValue(cell));break;case "class java.lang.Integer":field.set(t, (int) cell.getNumericCellValue());break;case "int":field.set(t, (int) cell.getNumericCellValue());break;case "class java.lang.Boolean":if("是".equals(getCellValue(cell))){field.set(t, true);}else{field.set(t, false);}break;case "class java.util.Date":SimpleDateFormat format = new SimpleDateFormat(dateFormat);if (cell != null) {if (cell.getCellType() == XSSFCell.CELL_TYPE_NUMERIC) {String dateStr = format.format(cell.getDateCellValue());field.set(t, format.parse(dateStr));} else {if (StringUtils.isBlank(cell.getStringCellValue())) {field.set(t, null);} else {field.set(t, format.parse(cell.getStringCellValue()));}}}break;default:break;}}}result.add(t);}return result;}/*** 获取单元格内容** @param cell 单元格* @return 单元格的值*/private Object getCellValue(XSSFCell cell) {Object value = null;if (cell != null) {switch (cell.getCellType()) {case XSSFCell.CELL_TYPE_STRING:value = cell.getStringCellValue();break;case XSSFCell.CELL_TYPE_NUMERIC:DecimalFormat df = new DecimalFormat("0");value = df.format(cell.getNumericCellValue()) + "";break;default:}}return value;}/*** 将列表转成文件流** @param clazz* @param ts* @return* @throws Exception*/public XSSFWorkbook listToExcel(Class<T> clazz, List<T> ts) throws Exception {return this.listToExcel(clazz, ts, null);}/*** 将列表转成文件流** @param clazz* @param ts* @return* @throws Exception*/public XSSFWorkbook listToExcel(Class<T> clazz, List<T> ts, String dataFormat) throws Exception {return this.listToExcel(clazz, ts, null, dataFormat);}/*** 将列表转成文件流** @param clazz* @param ts* @param sheetName* @return* @throws Exception*/public XSSFWorkbook listToExcel(Class<T> clazz, List<T> ts, String sheetName, String dateFormat) throws Exception {if (dateFormat == null) {dateFormat = "yyyy-MM-dd HH:mm";}XSSFWorkbook workbook = new XSSFWorkbook();this.createSheet(workbook, clazz, ts, (StringUtils.isBlank(sheetName)) ? "Sheet1" : sheetName, dateFormat, null, null);return workbook;}/*** 将列表转成文件流** @param clazz* @param ts* @param sheetName* @return* @throws Exception*/public XSSFWorkbook listToExcel(Class<T> clazz, List<T> ts, String sheetName, String dateFormat, SelectData selectData, List<Integer> lockedCols) throws Exception {if (dateFormat == null) {dateFormat = "yyyy-MM-dd HH:mm";}XSSFWorkbook workbook = new XSSFWorkbook();this.createSheet(workbook, clazz, ts, (StringUtils.isBlank(sheetName)) ? "Sheet1" : sheetName, dateFormat, selectData, lockedCols);return workbook;}/*** @param clazz* @param headerMap 表头字段属性集合 key 字段 value 字段含义(需有序)* @param ts* @param sheetName* @return* @throws Exception*/public XSSFWorkbook listToExcelByMap(Class<T> clazz, Map<String, String> headerMap, List<T> ts, String sheetName)throws Exception {XSSFWorkbook workbook = new XSSFWorkbook();this.createSheetByMap(workbook, headerMap, ts, clazz, (StringUtils.isBlank(sheetName)) ? "Sheet1" : sheetName);return workbook;}/*** 创建Excel的Sheet** @param workbook* @param clazz* @param data* @param sheetName* @param selectData 下拉值* @param lockedCols 锁定的列* @throws Exception*/private void createSheet(XSSFWorkbook workbook, Class clazz, List data, String sheetName, String dateFormat, SelectData selectData, List<Integer> lockedCols)throws Exception {Field[] fields = clazz.getDeclaredFields();Map<String, String> columnInfos = new LinkedHashMap<>();//设置表头XSSFSheet sheet = workbook.createSheet(sheetName);XSSFRow headRow = sheet.createRow(0);for (int i = 0; i < fields.length; i++) {ColumnName cn = fields[i].getAnnotation(ColumnName.class);if (cn != null) {XSSFCell cell = headRow.createCell(i);sheet.setColumnWidth(i, 5000);//用easyExcel设置表头cell.setCellStyle(StyleUtil.buildDefaultCellStyle(workbook));String fieldType = fields[i].getGenericType().toString();cell.setCellValue(cn.value());columnInfos.put(fields[i].getName(), fieldType);}}//列的下拉选择赋值if(selectData != null){//生成下拉框String[] datas = selectData.getDatas();XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint) dvHelper.createExplicitListConstraint(datas);CellRangeAddressList addressList = new CellRangeAddressList(selectData.getFirstRow(), selectData.getLastRow(), selectData.getFirstCol(), selectData.getLastCol());XSSFDataValidation validation = (XSSFDataValidation) dvHelper.createValidation(dvConstraint, addressList);sheet.addValidationData(validation);}sheet.protectSheet("111");//XSSFCellStyle bodyStyle = workbook.createCellStyle();XSSFCellStyle lockStyle =  workbook.createCellStyle();lockStyle.setLocked(true);//单元格不锁定的样式XSSFCellStyle unlockStyle =  workbook.createCellStyle();unlockStyle.setLocked(false);//bodyStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);//设置内容for (int i = 0; i < data.size(); i++) {XSSFRow row = sheet.createRow(i + 1);int j = 0;for (Map.Entry<String, String> entry2 : columnInfos.entrySet()) {String columnName = entry2.getKey();String methodName = "get" + columnName.substring(0, 1).toUpperCase() + columnName.substring(1);Method method = clazz.getDeclaredMethod(methodName);Object value = method.invoke(data.get(i));XSSFCell cell = row.createCell(j);//判断是否要锁定列if(lockedCols != null && lockedCols.contains(j)){cell.setCellStyle(lockStyle);}else{cell.setCellStyle(unlockStyle);}j++;if (value != null) {switch (entry2.getValue()) {case "class java.lang.String":cell.setCellValue((String) value);break;case "int":cell.setCellValue((int) value);break;case "class java.lang.Integer":cell.setCellValue((int) value);break;case "class java.lang.Boolean":cell.setCellValue((boolean) value);break;case "class java.util.Date"://SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);cell.setCellValue(sdf.format((Date) value));break;default:}} else {cell.setCellValue("");}}}}/*** 创建Excel的Sheet** @param workbook* @param headerMap 表头字段属性集合 key 字段 value 字段含义(需有序)* @param data* @param clazz* @param sheetName* @throws Exception boolean类型注意封装时的get/set方法*/private void createSheetByMap(XSSFWorkbook workbook, Map<String, String> headerMap, List data, Class clazz,String sheetName) throws Exception {//样式XSSFFont font = workbook.createFont();//font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);font.setColor(HSSFColor.BLUE.index);XSSFCellStyle headStyle = workbook.createCellStyle();headStyle.setFont(font);//headStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);//设置表头XSSFSheet sheet = workbook.createSheet(sheetName);XSSFRow headRow = sheet.createRow(0);int headerIdx = 0;for (Map.Entry<String, String> headerEntry : headerMap.entrySet()) {XSSFCell cell = headRow.createCell(headerIdx);cell.setCellType(XSSFCell.CELL_TYPE_STRING);sheet.setColumnWidth(headerIdx, 5000);cell.setCellStyle(headStyle);cell.setCellValue(headerEntry.getValue());headerIdx++;}XSSFCellStyle bodyStyle = workbook.createCellStyle();//bodyStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);//设置内容XSSFRow dataRow;Field field;Method method;XSSFCell cell;StringBuilder sb = new StringBuilder();for (int i = 0; i < data.size(); i++) {dataRow = sheet.createRow(i + 1);int j = 0;for (Map.Entry<String, String> headerEntry : headerMap.entrySet()) {field = clazz.getDeclaredField(headerEntry.getKey());sb.append("get").append(field.getName().substring(0, 1).toUpperCase()).append(field.getName().substring(1));method = clazz.getDeclaredMethod(sb.toString());sb.delete(0, sb.length());Object value = method.invoke(data.get(i));cell = dataRow.createCell(j++);cell.setCellStyle(bodyStyle);if (value != null) {switch (field.getType().getName()) {case "java.lang.String":cell.setCellValue((String) value);break;case "int":cell.setCellValue((int) value);break;case "java.lang.Integer":cell.setCellValue((int) value);break;case "java.lang.Boolean":cell.setCellValue((boolean) value);break;case "java.util.Date":SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");cell.setCellValue(sdf.format((Date) value));break;default:}} else {cell.setCellValue("");}}}}
}

demo

@GetMapping("/exportExcel")public void exportExcel(HttpServletResponse response) throws Exception {List<Person> list=new ArrayList<>();Person p1=new Person("末日");Person p2=new Person("神灵");list.add(p1);list.add(p2);String[] datas = new String[] {"部门","科室","岗位 "};SelectData selectData = new SelectData(datas, 1, 100, 0, 0);XSSFWorkbook applicantExcel = poiExcelUtil.listToExcel(Person.class, list, "kongtest", "yyyy-MM-dd", selectData);// 输出附件response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("下拉选择.xlsx", "UTF-8"));OutputStream outStream = response.getOutputStream();applicantExcel.write(outStream);outStream.flush();}导入Map<String,Object> result = excelUtil.readExcel(file, new Person(),1);List<Person> excelImports = new ArrayList<>();Boolean flag = (Boolean) result.get("flag");Response response;List<Object> list;if(flag){list = (List<Object>) result.get("datas");if(list != null && list.size() > 0){list = (List<Object>) result.get("datas");}else{return BaseUtil.createResponse(ReturnCode.ERROR, "",         Arrays.asList(ReturnMessage.IMPORT_NULL));}}else{return BaseUtil.createResponse(ReturnCode.ERROR, "", Arrays.asList(ReturnMessage.EXCEL_HEAD_ERROR));}

springboot导出excel(easyexcel和poi 列下拉及表格锁定)相关推荐

  1. Java动态生成excel模板文件(包含列下拉)

    1.添加依赖 <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> <dependency><gr ...

  2. easyExcel导出数据并设置单元格下拉数据

    easyExcel由于导出和导入的注解差异,所以实现不了标题功能 此处不在介绍导出导出的注解 entity: @DropDownSetField自行封装注解:稍后解释 public class Sal ...

  3. Springboot导出excel,合并单元格示例

    原文链接:Springboot导出excel,合并单元格示例 更多文章,欢迎访问:Java知音,一个专注于技术分享的网站 以下用一个示例来说明springboot如何导出数据到excel. 首先引入M ...

  4. Excel导出模板加数据时,下拉框丢失解决方案

    简介: 在工作中.我们大多数会碰到导出.导入excel功能.此篇文档便是对导出时,模板中自带的下拉框丢失的问题记录. 摘要: 首先简要描述如何实现excel导出模板加数据功能. 1.读取sheet模板 ...

  5. java excel中重复数据 事务处理_Java导出excel时合并同一列中相同内容的行思路详解...

    一.有时候导出Excel时需要按类别导出,一大类下好几个小类,小类下又有好几个小小类,就像下图: 要实现这个也不难, 思路如下:按照大类来循环,如上就是按照张江校区.徐汇校区.临港校区三个大类循环,然 ...

  6. java 导出如何合并列_Java导出excel时合并同一列中相同内容的行思路详解

    一.有时候导出Excel时需要按类别导出,一大类下好几个小类,小类下又有好几个小小类,就像下图: 要实现这个也不难, 思路如下:按照大类来循环,如上就是按照张江校区.徐汇校区.临港校区三个大类循环,然 ...

  7. excel添加列下拉框票价_excel表格下拉表格添加数据-excel2017表格中怎么制作下拉菜单列表框...

    在Excel表中,如何将增加下拉菜单的选项? excel中的下拉菜单选项,就是筛选的功能,具体操作如下: 1.首先选中a.b两列数据,在"开始"选项卡上选择"筛选&quo ...

  8. Excel技巧 - 根据A列内容显示B列下拉菜单

    Excel如何通过A列的内容,对应选择B列下拉菜单的列表信息. 比如D列是一级分类,有不同的元素,E列根据不同的元素有不同的分列列表.我们可以使用偏移函数OFFSET来实现. 1.列举辅助信息表 首先 ...

  9. 基于注解和EasyExcel指定单元格下拉选内容

    基于注解和EasyExcel指定单元格下拉选内容 1.场景描述 要求基于EasyExcel进行导出,有的单元格的内容必须是通过下拉选内容进行编辑,以便于后续修改导入,规避用户随意录入数据. 2.编写测 ...

最新文章

  1. VC++关于UNICODE版本的开发
  2. 搭建redis给mysql做缓存
  3. 满纸荒唐言,一把辛酸泪--红楼一梦
  4. 净资产滚动率_净资产的结构
  5. xxx is not in the sudoers file.This incident will be reported.
  6. Mysql根据顺序合并数据
  7. dbus PHP,安装dbus-python的简要教程
  8. React学习笔记:入门案例
  9. java trunc函数_TRUNC函数的用法
  10. devops handbook 读书笔记_DevOps教程:DevOps 面试题
  11. 网络故障排除连载之四:OSPF故障排除
  12. 开发小技巧: 如何在jQuery中禁用或者启用滚动事件.scroll
  13. Qt之QPA(linuxfb 一)
  14. linux应用项目(一)数码相框(2)数码相框之字符编码与字符的点阵显示
  15. uva_10066 The Twin Towers
  16. 520男生送什么礼物好、实用小礼物合集
  17. 凌晨三点的程序员,别让你的辛苦被辜负
  18. ubuntu更新软件包命令_从Ubuntu命令行查看哪些更新的软件包可用
  19. 计算机网络习题:第三单元
  20. 第六届中国软件开源创新大赛——飞桨赛题新鲜出炉,速来pick!

热门文章

  1. linux添加扩展gpio,嵌入式Linux工控板的ISA总线GPIO扩展
  2. OpenGL---GLUT教程(四) GLUT动画
  3. PHP实现生成推广海报的方法详解
  4. 2021威海高考成绩查询电话,2021威海高考成绩查询系统
  5. G-S稳定匹配算法详解
  6. 电商不仅仅有CRUD——0基础了解电商中的引流工具谷歌GMC
  7. 知乎引流、知乎带货工具、知乎选品、数据分析、带货软件(1)
  8. AlexNet分类Fashi-MNIST(Pytorch实现)
  9. ctr 平滑_根据样本数进行点击率CTR的修正 - Wilson CTR
  10. 《千万别学英语》精粹