SpringBoot通过WorkBook快速实现对Excel的导入和导出(包括数据校验)

private BaseRecordCheck recordCheck;

/**

  • 入表处理器

*/

private BaseInsertService insertHandle;

public BatchImportStruBO(List importTitles, BaseRecordCheck recordCheck, BaseInsertService insertHandle) {

this.importTitles = importTitles;

this.recordCheck = recordCheck;

this.insertHandle = insertHandle;

}

}

5、Spring帮助类

/**

  • @Description:Spring帮助类

  • @Author:zhangzhixaing

  • @CreateDate:2018/08/31 16:39:45

  • @Version:1.0

*/

@Component

public class SpringHelper implements ApplicationContextAware {

private static ApplicationContext applicationContext = null;

@Override

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

if(SpringHelper.applicationContext == null) {

SpringHelper.applicationContext = applicationContext;

}

}

/**

  • 根据一个bean的id获取配置文件中相应的bean

*/

public static Object getBean(String beanId) throws BeansException {

if(applicationContext.containsBean(beanId)) {

applicationContext.getBean(beanId);

}

return null;

}

/**

  • 根据一个bean的类型获取配置文件中相应的bean

*/

public static T getBeanByClass(Class requiredType) throws BeansException {

return applicationContext.getBean(requiredType);

}

/**

  • 如果BeanFactory包含一个与所给名称匹配的bean的定义,则返回true,否则false

*/

public static boolean containsBean(String name) {

return applicationContext.containsBean(name);

}

/**

  • 获取Spring容器

*/

public static ApplicationContext getApplicationContext() {

return SpringHelper.applicationContext;

}

}

6、String帮助类

/**

  • @Description:String帮助类

  • @Author:zhangzhixaing

  • @CreateDate:2018/08/31 16:39:45

  • @Version:1.0

*/

public class StringHelper extends StringUtils {

public StringHelper() {}

/**

  • 判断是否为空

*/

public static boolean isBlankAnyWay(String str) {

return isBlank(str) || “null”.equalsIgnoreCase(str);

}

/**

  • 判断是否非空

*/

public static boolean isNotBlankAnyWay(String str) {

return !isBlankAnyWay(str);

}

/**

  • 将null转为空

*/

public static String nullToEmpty(String str) {

return Strings.nullToEmpty(str);

}

/**

  • 将空转为null

*/

public static String emptyToNumm(String str) {

return Strings.emptyToNull(str);

}

/**

  • 左填充

*/

public static String padStart(String str, int minLength, char padChar) {

return Strings.padStart(str, minLength, padChar);

}

/**

  • 右填充

*/

public static String padEnd(String str, int minLength, char padChar) {

return Strings.padEnd(str, minLength, padChar);

}

}

7、Excel单元格

/**

  • @Description:Excel单元格实体

  • @Author:zhangzhixaing

  • @CreateDate:2018/08/31 16:39:45

  • @Version:1.0

*/

@Data

public class BaseColumn {

/**

  • 常量定义

*/

public static final Boolean TRUE = true;

public static final Boolean FALSE = false;

/**

  • Excel中对应的字段名称

*/

protected String excelName;

/**

  • Excel字段值

*/

protected String excelValue;

/**

  • 是否必填

*/

protected Boolean isRequired;

/**

  • 值得校验是否成功,默认true

*/

protected boolean checkIsSuccess = true;

/**

  • 校验结果信息

*/

protected String checkMessage;

public BaseColumn() {

super();

}

public BaseColumn(String excelName, Boolean isRequired) {

super();

this.excelName = excelName;

this.isRequired = isRequired;

}

public BaseColumn(String excelName) {

super();

this.excelName = excelName;

}

}

8、行校验接口

/**

  • @Description:行校验接口

  • @Author:zhangzhixiang

  • @CreateDate:2018/08/31 21:56:32

  • @Version:1.0

*/

public interface BaseRecordCheck {

/**

  • 记录校验

  • @param cells

  • @return

  • @throws Exception

*/

List valueCheck(List cells) throws Exception;

}

9、线索行校验实现

/**

  • @Description:线索行校验

  • @Author:zhangzhixiang

  • @CreateDate:2018/08/31 12:59:48

  • @Version:1.0

*/

public class ClueRecordCheck implements BaseRecordCheck {

@Override

public List valueCheck(List cells) throws Exception {

//字段校验

for (BaseColumn column : cells) {

switch (column.getExcelName()) {

case BatchImportConsts.EXCEL_CLUE_RECORD_COLUMN_NAME:

new BaseCheck().valueCheck(column);

break;

case BatchImportConsts.EXCEL_CLUE_RECORD_COLUMN_ID_CARD:

new ClueIdcardCheck().valueCheck(column);

break;

case BatchImportConsts.EXCEL_CLUE_RECORD_COLUMN_IPHONE:

new CluePhoneCheck().valueCheck(column);

break;

case BatchImportCONsts.EXCEL_CLUE_RECORD_COLUMN_SEX:

new ClueSexCheck().valueCheck(column);

break;

default:

break;

}

}

return cells;

}

}

10、列校验接口

/**

  • @Description:列校验接口

  • @Author:zhangzhixiang

  • @CreateDate:2018/08/31 21:56:34

  • @Version:1.0

*/

public interface BaseColumnCheck {

/**

  • 校验字段值

  • @param cell

  • @return

  • @throws Exception

*/

BaseColumn valueCheck(BaseColumn cell) throws Exception;

/**

  • 多字段联合校验

  • @param cells

  • @return

  • @throws Exception

*/

List valueCheck(List cells) throws Exception;

}

11、线索列校验实现(基础非空校验)

/**

  • @Description:基础非空校验

  • @Author:zhangzhixiang

  • @CreateDate:2018/08/31 21:59:43

  • @Version:1.0

*/

public class BaseCheck implements BaseColumnCheck {

private static final String EMPTY_MESSAGE = “不能为空;”

@Override

public BaseColumn valueCheck(BaseColumn cell) throws Exception {

if (StringUtils.isBlank(cell.getExcelValue())) {

cell.setCheckIsSuccess(false);

cell.setCheckMessage((cell.getCheckMessage() == null ? “” : cell.getCheckMessage()) + cell.getExcelName() + EMPTY_MESSAGE);

} else {

cell.setCheckIsSuccess(true);

}

return cell;

}

@Override

public List valueCheck(List cells) throws Exception {

return null;

}

}

12、线索列校验实现(身份证号校验)

/**

  • @Description:身份证号校验

  • @Author:zhangzhixiang

  • @CreateDate:2018/08/31 21:59:43

  • @Version:1.0

*/

public class ClueIdcardCheck implements BaseColumnCheck {

private static final String EMPTY_MESSAGE = “不能为空;”;

private static final String WRONG_MESSAGE = “格式不对;”;

@Override

public BaseColumn valueCheck(BaseColumn cell) throws Exception {

if(cell.getIsRequired() || (!cell.getIsRequired() && StringHelper.isNotBlankAnyWay(cell.getExcelValue()))) {

cell.setCheckIsSuccess(false);

cell.setCheckMessage((cell.getCheckMessage() == null ? “” : cell.getCheckMessage()) + cell.getExcelName() + EMPTY_MESSAGE);

} else {

//校验身份证号合法性

String reg = “^\d{15}KaTeX parse error: Got function '\\' with no arguments as superscript at position 3: |^\̲\̲d{17}[0-9Xx]”;

if(!cell.getExcelValue().matches(reg)) {

cell.setCheckIsSuccess(false);

cell.setCheckMessage((cell.getCheckMessage() == null ? “” : cell.getCheckMessage()) + cell.getExcelName() + WRONG_MESSAGE);

}

}

return cell;

}

@Override

public List valueCheck(List cells) throws Exception {

return null;

}

}

13、线索列校验实现(手机号校验)

/**

  • @Description:手机号校验

  • @Author:zhangzhixiang

  • @CreateDate:2018/08/31 21:59:43

  • @Version:1.0

*/

public class CluePhoneCheck implements BaseColumnCheck {

private static final String EMPTY_MESSAGE = “不能为空;”

private static final String WRONG_MESSAGE = “格式不对;”

private Pattern p = Pattern.compile(“((13[0-9])|(15[4,\D])|(18[0,5-9]))\d{8}$”);

@Override

public BaseColumn valueCheck(BaseColumn cell) throws Exception {

if(cell.getRequired() || (!cell.getRequired() && StringHelper,isNotBlankAnyWay(cell.getExcelValue()))) {

cell.setCheckIsSuccess(false);

cell.setCheckMessage((cell.getCheckMessage() == null ? “” : cell.getCheckMessage()) + cell.getExcelName() + EMPTY_MESSAGE);

} else {

//校验手机号合法性

Matcher m = p.matcher(cell.getExcelValue());

if(!m.matches()) {

cell.setCheckIsSuccess(false);

cell.setCheckMessage((cell.getCheckMessage() == null ? “” : cell.getCheckMessage()) + cell.getExcelName() + WRONG_MESSAGE);

}

}

return cell;

}

@Override

public List valueCheck(List cells) throws Exception {

return null;

}

}

14、线索列校验实现(性别校验)

/**

  • @Description:性别校验

  • @Author:zhangzhixiang

  • @CreateDate:2018/08/31 21:59:43

  • @Version:1.0

*/

public class ClueSexCheck implements BaseColumnCheck {

private static final String EMPTY_MESSAGE = “不能为空;”

private static final String WRONG_MESSAGE = “格式不对;”

private String man = “男”;

private String women = “女”;

@Override

public BaseColumn valueCheck(BaseColumn cell) throws Exception {

if(cell.getRequired() || (!cell.getRequired() && StringHelper,isNotBlankAnyWay(cell.getExcelValue()))) {

cell.setCheckIsSuccess(false);

cell.setCheckMessage((cell.getCheckMessage() == null ? “” : cell.getCheckMessage()) + cell.getExcelName() + EMPTY_MESSAGE);

} else {

//校验手机号合法性

Matcher m = p.matcher(cell.getExcelValue());

if(!m.matches()) {

if(!(man.equals(cell.getExcelValue()) || women.equals(cell.getExcelValue()))) {

cell.setCheckIsSuccess(false);

cell.setCheckMessage((cell.getCheckMessage == null ? “” : cell.getCheckMessage()) + cell.getExcelName() + WRONG_MESSAGE);

}

}

}

return cell;

}

@Override

public List valueCheck(List cells) throws Exception {

return null;

}

}

15、Excel入库接口

/**

  • @Description:Excel入库接口

  • @Author:zhangzhixiang

  • @CreateDate:2018/08/31 21:59:43

  • @Version:1.0

*/

public interface BaseInsertService {

/**

  • Excel数据入库

  • @param rows Excle数据

  • @param isSuccess

  • @author zhangzhixiang

  • @data 2018/09/19 18:56:43

*/

void insertDB(List<List> rows, Boolean isSuccess) throws Exception;

}

16、Excel入库实现(线索)

/**

  • @Description:Excel线索入库接口

  • @Author:zhangzhixiang

  • @CreateDate:2018/08/31 21:59:43

  • @Version:1.0

*/

@Service

public class ClueInsertServiceImpl implements BaseInsertService {

@Autowired

public ClueInfoDAO clueInfoDAO;

@Override

@Transactional(rollbackFor = Exception.class)

public void insertDB(List<List> rows, Boolean isSuccess) throws Exception {

//线索自定义入库代码

}

}

17、Excel公共服务接口(OSS)

/**

  • @Description:Excel服务接口(OSS)

  • @Author:zhangzhixiang

  • @CreateDate:2018/08/31 21:59:43

  • @Version:1.0

*/

public interface ExcelOperateService {

/**

  • Excel文件导入

  • @param fileName 原文件名

  • @param code 文件唯一标示

  • @param model Excel类型标识

  • @return 解析结果

  • @throws Exception

*/

ExcelParseResultBO excelImport(String code, String model) throws Exception;

/**

  • Excel文件导出

  • @param response

  • @param rows 需要导出的数据

  • @param fileName 文件名

  • @param sheetName sheet名

  • @return void

  • @author zxzhang

  • @date 2019/10/10

*/

void excelExport(HttpServletResponse response, List<List> rows, String fileName, String sheetName) throws Exception;

}

18、Excel公共服务实现(OSS)

/**

  • @Description:Excel公共服务实现(OSS)

  • @Author:zhangzhixiang

  • @CreateDate:2018/08/31 21:59:43

  • @Version:1.0

*/

@Service

public class ExcelOperateServiceImpl implements ExcelOperateService {

private static final Logger logger = LoggerFactory.getLogger(ExcelOperateServiceImpl.class);

private static final String SERVICE_ERROR_MESSAGE = “批量导入失败”;

/**

  • Excel文件导入

  • @param code OSS文件唯一标示

  • @param model 业务类型(clue、report)

  • @return 解析结果

  • @throws Exception

*/

@Override

public ExcelOperateBO excelImport(String code, String model) throws Exception {

FileClient client = ClientFactory.createClientByType(BootstrapConsts.file_client_type);

ExcelOperateBO resultBO = null;

//1、获取Excel数据

List<List> excelDatas = null;

excelDatas = ExcelRead.getSheetDataWithTitle(client.getFileStream(code), code, null);

String message;

if(null == excelDatas || excelDatas.size() < SimpleConst.TWO) {

message = “文件无有效数据”;

resultBO = new ExcelOperateBO();

resultBO.setFileOK(false);

resultBO.setMessage(message);

return resultBO;

}

logger.info(“记录数量:” + excelDatas.size());

//2、校验标题合法性

resultBO = excelTitleCheck(excelDatas.get(0), model);

if(!resultBO.getFileOK()) {

return resultBO;

}

//3、将Excel中的每列数据与title名称绑定

List<List> excelRows = null;

excelRows = getExcelData(excelDatas, model);

if(null == excelRows || excelRows.size() == 0) {

resultBO = new ExcelOperateBO();

resultBO.setTotalNum(0);

resultBO.setSuccessNum(0);

resultBO.setFailNum(0);

resultBO.setFileOK(true);

return resultBO;

}

//4、Excel数据校验

List<List> successRows = new ArrayList<>();

List<List> failRows = new ArrayList<>();

rowsCheck(excelRows, model, successRows, failRows);

//5、入库

if(successRows.size() > 0) {

insertdb(successRows, model, true);

}

if(failRows.size() > 0) {

insertdb(failRows, model, false);

}

return resultBO;

}

/**

  • Excel文件导出

  • @param response

  • @param rows 导出文件内容(包括标题)

  • @param fileName 导出文件名

  • @param sheetName sheet名称

  • @return 解析结果

  • @throws Exception

*/

@Override

public void excelExport(HttpServletResponse response, List<List> rows, String fileName, String sheetName) throws Exception {

ExcelWrite.exportExcel(response, rows, fileName, sheetName);

}

/**

  • 数据入库

  • @param rows 待写入的数据

  • @param model 业务类型(clue、report)

  • @param isSuccess 是否成功

*/

private void insertdb(List<List> rows, String model, Boolean isSuccess) throws Exception {

BatchImportStruBO struBO = ExcelTypeEnum.containKey(model).getStruBO();

BaseInsertService insertHandle = struBO.getInsertHandle();

insertHandle.insertDB(rows, isSuccess);

}

/**

  • Excek数据校验

  • @param excelRows 待校验数据

  • @param model 业务类型(clue、report)

  • @param successRows 校验成功的数据

  • @param failRows 校验失败的数据

*/

private void rowsCheck(List<List> excelRows, String model, List<List> successRows, List<List> failRows) throws Exception {

BaseRecordCheck recordCheck = ExcelTypeEnum.containKey(model).getStruBO().getRecordCheck();

List checkedRow = null;

boolean isSuccessCheck = true;

for (List rowData : excelRows) {

checkedRow = recordCheck.valueCheck(rowData);

if(checkedRow == null || checkedRow.size() == 0) {

continue;

}

for (BaseColumn cell : checkedRow) {

if (!cell.isCheckIsSuccess()) {

isSuccessCheck = cell.isCheckIsSuccess();

break;

}

}

if(!isSuccessCheck) {

failRows.add(checkedRow);

} else {

successRows.add(checkedRow);

}

isSuccessCheck = true;

}

}

/**

  • 获取Excel有效数据(将title与Excel数据绑定)

  • @param excelDatas Excel数据

  • @return

  • @throws Exception

*/

private List<List> getExcelData(List<List> excelDatas, String model) throws Exception {

BatchImportStruBO batchImportStruBO = ExcelTypeEnum.containKey(model).getStruBO();

List titles = batchImportStruBO.getImportTitles();

excelDatas.remove(0);

for(int i = 0; i<excelDatas.size(); i++) {

List row = valueTrim(excelDatas.get(i));

excelDatas.set(i, row);

}

List<List> excelRows = excelDataTidy(titles, excelDatas);

if (null == excelRows) {

throw new Exception(“excelDatas数据转为excelRows数据报错”);

}

return excelRows;

}

/**

  • 将标题和具体的数据组合

  • @param titles 标题信息

  • @param rowList 记录数据,其中记录的字段索引与对应的标题索引一致

  • @return

*/

private List<List> excelDataTidy(List titles, List<List> rowList) {

List<List> datas = new ArrayList<>();

List rowData = null;

BaseColumn cellData = null;

List excelRow = null;

for(int i = 0; i < rowList.size(); i++) {

rowData = new ArrayList<>();

excelRow = rowList.get(i);

for(int j = 0; j < excelRow.size(); j++) {

String excelCellValue = excelRow.get(j);

String title = null;

if(j < titles.size()) {

title = titles.get(j).getExcelName();

} else {

break;

}

cellData = new BaseColumn();

cellData.setExcelName(title);

cellData.setIsRequired(titles.get(j).getIsRequired());

cellData.setExcelValue(excelCellValue);

rowData.add(cellData);

}

datas.add(rowData);

}

return datas;

}

/**

  • 校验标题是否合规

  • @param titles 标题信息

  • @param model 业务类型(clue、report)

  • @return

*/

private ExcelOperateBO excelTitleCheck(List titles, String model) throws Exception {

BatchImportStruBO batchImportStruBO = ExcelTypeEnum.containKey(model).getStruBO();

String message = “解析标题报错”;

titles = valueTrim(titles);

List orderTitles = batchImportStruBO.getImportTitles();

boolean titleCheck = titleCheck(titles, orderTitles);

if (!titleCheck) {

throw new Exception(message);

}

ExcelOperateBO resultBO= new ExcelOperateBO();

resultBO.setFileOK(true);

return resultBO;

}

/**

  • 校验Excel中标题是否包含所需要的标题

  • @param titles 标题信息

  • @param orderTitles 要求的标题信息

  • @return

*/

private boolean titleCheck(List titles, List orderTitles) {

if (null == titles || titles.size() == 0) {

return false;

}

if(null == orderTitles || orderTitles.size() == 0) {

return false;

}

List names = new ArrayList<>();

for (BaseColumn column : orderTitles) {

names.add(column.getExcelName());

}

for (String name : names) {

if(!titles.contains(name)) {

return false;

}

}

return true;

}

/**

  • 去除首尾无效空格

  • @param values 要去空格的字符串

  • @return

*/

private List valueTrim(List values) {

if(null == values || values.size() == 0) {

return values;

}

for(int i=0; i < values.size(); i++) {

if(StringUtils.isBlank(values.get(i))) {

values.set(i, null);

continue;

} else {

values.set(i, values.get(i).trim());

}

}

return values;

}

}

19、Excel基础操作

/**

  • @Description:Excel基础操作

  • @Author:zhangzhixiang

  • @CreateDate:2018/08/31 21:59:43

  • @Version:1.0

*/

public class ExcelBaseOperate {

private static final Logger logger = LoggerFactory.getLogger(ExcelBaseOperate.class);

private static final String SUFFIX_XLS = “xls”;

private static final String SUFFIX_XLSX = “xlsx”;

/**

  • 获取Excel操作类

  • @param inputStream

  • @param name

  • @return

  • @throws Exception

*/

public static Workbook getWorkbook(InputStream inputStream, String name) throws Exception {

Workbook wb = null;

if (name.endsWith(SUFFIX_XLSX)) {

wb = new XSSFWorkbook(OPCPackage.open(inputStream));

} else if (name.endsWith(SUFFIX_XLS)) {

wb = WorkbookFactory.create(inputStream);

} else {

String errorMessage = “无法识别的文件类型。文件名称:” + name;

logger.error(errorMessage);

throw new Exception(errorMessage);

}

return wb;

}

}

20、Excel读取操作

/**

  • @Description:Excel读取操作

  • @Author:zhangzhixiang

  • @CreateDate:2018/08/31 21:59:43

  • @Version:1.0

*/

public class ExcelRead {

private static final Logger logger = LoggerFactory.getLogger(ExcelRead.class);

private static SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);

/**

  • 获取sheet页标题

  • @param inputStream Excel文件流

  • @param excelName Excel文件名

  • @param sheetName sheet页名称。不输入则默认取第一个sheet

  • @return

*/

public static List getSheetTitle(InputStream inputStream, String excelName, String sheetName) throws Exception {

Workbook workbook = ExcelBaseOperate.getWorkbook(inputStream, excelName);

//没有输入sheetname,则默认第一个sheet

if (StringUtils.isBlank(sheetName)) {

sheetName = workbook.getSheetAt(0).getSheetName();

}

List<List> sheetData = parseSheet(workbook, sheetName, 0, 0);

if(null == sheetData || sheetData.size() == 0) {

return null;

}

return sheetData.get(0);

}

/**

  • 获取带标题的sheet页数据

  • @param inputStream Excel文件流

  • @param excelName Excel文件名

  • @param sheetName sheet页名称。不输入则默认取第一个sheet

  • @return

*/

public static List<List> getSheetDataWithTitle(InputStream inputStream, String excelName, String sheetName) throws Exception {

Workbook workbook = ExcelBaseOperate.getWorkbook(inputStream, excelName);

//没有输入sheetname,则默认第一个sheet

if (StringUtils.isBlank(sheetName)) {

sheetName = workbook.getSheetAt(0).getSheetName();

}

List<List> sheetData = parseSheet(workbook, sheetName, 0, workbook.getSheet(sheetName).getPhysicalNumberOfRows());

return sheetData;

}

/**

  • 解析sheet页数据

  • @param wb Excel文件

  • @param sheetName sheet页名称

  • @param startIndex 解析的起始row,从0开始,包含此row

  • @param endIndex 解析的终止row,从0开始,包含此row

  • @return 第一层list:row;第二层list:cell

*/

private static List<List> parseSheet(Workbook wb, String sheetName, int startIndex, int endIndex) throws Exception {

String message = null;

Sheet sheet = wb.getSheet(sheetName);

if(null == sheet) {

message = sheetName + “,此sheet页不存在”;

throw new Exception(message);

}

int lastRowNum = sheet.getPhysicalNumberOfRows();

if(startIndex < 0 || endIndex > lastRowNum || startIndex > endIndex) {

message = “输入的解析row范围错误。startIndex:” + startIndex + “,endIndex:” + endIndex;

throw new Exception(message);

}

List<List> sheetData = new ArrayList<>();

int cellCount = -1;

//row list

for (int i = startIndex; i < endIndex; i++) {

Row row = sheet.getRow(i);

if(null == row) {

continue;

}

List rowData = new ArrayList<>();

cellCount = row.getLastCellNum();

//cell list

for(int j = 0; j < cellCount; j++) {

Cell cell = row.getCell(j);

if(null == cell) {

rowData.add(null);

continue;

}

rowData.add(getCellValue(cell));

}

sheetData.add(rowData);

}

return sheetData;

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

现在正是金三银四的春招高潮,前阵子小编一直在搭建自己的网站,并整理了全套的**【一线互联网大厂Java核心面试题库+解析】:包括Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等**

image
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
";

throw new Exception(message);

}

int lastRowNum = sheet.getPhysicalNumberOfRows();

if(startIndex < 0 || endIndex > lastRowNum || startIndex > endIndex) {

message = “输入的解析row范围错误。startIndex:” + startIndex + “,endIndex:” + endIndex;

throw new Exception(message);

}

List<List> sheetData = new ArrayList<>();

int cellCount = -1;

//row list

for (int i = startIndex; i < endIndex; i++) {

Row row = sheet.getRow(i);

if(null == row) {

continue;

}

List rowData = new ArrayList<>();

cellCount = row.getLastCellNum();

//cell list

for(int j = 0; j < cellCount; j++) {

Cell cell = row.getCell(j);

if(null == cell) {

rowData.add(null);

continue;

}

rowData.add(getCellValue(cell));

}

sheetData.add(rowData);

}

return sheetData;

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-80VGWueI-1713414684489)]

[外链图片转存中…(img-nI28svCF-1713414684489)]

[外链图片转存中…(img-dSViQJBX-1713414684490)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

现在正是金三银四的春招高潮,前阵子小编一直在搭建自己的网站,并整理了全套的**【一线互联网大厂Java核心面试题库+解析】:包括Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等**

[外链图片转存中…(img-hJEo3S4j-1713414684490)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值