springboot SpringBoot excel 导入 导出 下载 excel
<!-- 解析excel poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<!-- 解析excel poi -->
/**
* 通用方法:将单元格内容转为字符串
* 数值型精度保留 通过 DataFormatter 直接获取单元格显示值,保留原始精度(如 12.34 不会转为 12)。
* @param cell
* @return
*/
private static String getCellValueAsString(Cell cell) {
if (cell == null) return "";
DataFormatter formatter = new DataFormatter();
FormulaEvaluator evaluator = cell.getSheet().getWorkbook().getCreationHelper().createFormulaEvaluator();
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue().trim();
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
// 日期格式化为 yyyy-MM-dd
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(cell.getDateCellValue());
} else {
// 数值型保留原始精度(不强制转整数)
return formatter.formatCellValue(cell);
}
case BOOLEAN:
return cell.getBooleanCellValue() ? "是" : "否"; // 本地化映射
case FORMULA:
// 获取公式计算结果
return formatFormulaValue(cell, evaluator);
case ERROR:
return "#ERROR"; // 标识错误单元格
default:
return "";
}
}
// 处理公式计算结果
private static String formatFormulaValue(Cell cell, FormulaEvaluator evaluator) {
try {
CellValue cellValue = evaluator.evaluate(cell);
switch (cellValue.getCellType()) {
case STRING:
return cellValue.getStringValue();
case NUMERIC:
return String.valueOf(cellValue.getNumberValue());
case BOOLEAN:
return cellValue.getBooleanValue() ? "是" : "否";
default:
return "";
}
} catch (Exception e) {
return "#FORMULA_ERROR";
}
}
// 辅助方法:根据身份证号解析性别
private static String getGenderFromIdCard(String idCard) {
if (idCard == null || idCard.length() < 15) {
return "未知"; // 无效身份证号
}
// 兼容15位和18位身份证
int genderDigitIndex = (idCard.length() == 15) ? 14 : 16;
char genderChar = idCard.charAt(genderDigitIndex);
// 判断奇偶性
if (!Character.isDigit(genderChar)) {
return "未知"; // 非数字字符
}
int genderCode = Character.getNumericValue(genderChar);
return (genderCode % 2 == 1) ? "男" : "女";
}
读取一切正常。
//第0行是 表头 第1行是数据 。
Row headerRow = sheet.getRow(0);
//查看这个row有多少列 因为这0 row是表头,我想输出所有表头。
for (int i = 0; i < headerRow.getLastCellNum(); i++) {
Cell cell = headerRow.getCell(i, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
String headerText;
// 处理不同类型的单元格值
//表头是,学籍号、篮球运球、足球运球 告诉我在第几列
switch (cell.getCellType()) {
case STRING:
headerText = cell.getStringCellValue().trim();
break;
case NUMERIC:
headerText = String.valueOf(cell.getNumericCellValue()).trim();
break;
case BOOLEAN:
headerText = String.valueOf(cell.getBooleanCellValue()).trim();
break;
default:
headerText = "";
}
// 匹配目标表头并记录列号
if ("学籍号".equals(headerText)) {
xuejiHaoColumn = i;
} else if ("篮球运球".equals(headerText)) {
basketballColumn = i;
} else if ("足球运球".equals(headerText)) {
footballColumn = i;
}
headers.add(headerText);
}
System.out.println(headers.toString());
// 输出结果
System.out.println("表头列号:");
System.out.println("学籍号 -> " + (xuejiHaoColumn != -1 ? "第" + (xuejiHaoColumn + 1) + "列" : "未找到"));
System.out.println("篮球运球 -> " + (basketballColumn != -1 ? "第" + (basketballColumn + 1) + "列" : "未找到"));
System.out.println("足球运球 -> " + (footballColumn != -1 ? "第" + (footballColumn + 1) + "列" : "未找到"));
for (int rowNum =1; rowNum <= sheet.getLastRowNum(); rowNum++) {
Row row = sheet.getRow(rowNum);
if (row == null) {
continue;
}
obj = new JSONObject();
//把获取 的学籍号 篮球运球 足球运球 放到obj里面
// 提取学籍号(空值跳过)
if (xuejiHaoColumn != -1) {
Cell cell = row.getCell(xuejiHaoColumn, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
String xuejiHaoValue = getCellValueAsString(cell);
// 关键判断:非空时才添加到 JSON
if (!xuejiHaoValue.isEmpty()) {
obj.put("学籍号", xuejiHaoValue);
// 根据身份证号判断性别
String gender = getGenderFromIdCard(xuejiHaoValue);
obj.put("性别", gender);
// 提取篮球运球
if (basketballColumn != -1) {
Cell cell2 = row.getCell(basketballColumn, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
String cell2_str = getCellValueAsString(cell2);
if(StringUtil.isNotEmpty(cell2_str)){
obj.put("篮球运球", cell2_str);
if(gender.equals("女")){
obj.put("篮球运球成绩", LanQiuUtil.getLanQiuNv(new BigDecimal(getCellValueAsString(cell2))));
}else{
obj.put("篮球运球成绩", LanQiuUtil.getLanQiuNan(new BigDecimal(getCellValueAsString(cell2))));
}
}
}
// 提取足球运球
if (footballColumn != -1) {
Cell cell3 = row.getCell(footballColumn, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
String cell3_str = getCellValueAsString(cell3);
if(StringUtil.isNotEmpty(cell3_str)) {
obj.put("足球运球", getCellValueAsString(cell3));
if(gender.equals("女")){
obj.put("足球运球成绩", ZuQiuUtil.getZuQiuNv(new BigDecimal( getCellValueAsString(cell3))));
}else{
obj.put("足球运球成绩", ZuQiuUtil.getZuQiuNan(new BigDecimal( getCellValueAsString(cell3))));
}
}
}
dataList.add(obj);
}
}
}
}
dataList.forEach(item->{
System.out.println(item.toString());
}); // 在循环外部创建数字格式(避免重复创建样式提升性能)
CellStyle numberStyle = wb.createCellStyle();
numberStyle.setDataFormat(wb.createDataFormat().getFormat("0.00"));
for(JSONObject obj : list) {
row = sheet.createRow(rowIndex);
row.createCell(0).setCellValue(obj.getString("sfz"));
row.createCell(1).setCellValue(obj.getString("gender"));
if(obj.containsKey("zuqiu")){
Cell cell = row.createCell(4);
cell.setCellValue(obj.getBigDecimal("zuqiu").doubleValue()); // 转换为 double
cell.setCellStyle(numberStyle); // 应用样式
}
if(obj.containsKey("zuqiu_score")){
Cell cell = row.createCell(5);
cell.setCellValue(obj.getBigDecimal("zuqiu_score").doubleValue()); // 转换为 double
cell.setCellStyle(numberStyle); // 应用样式
}
rowIndex++;
}站长微信:xiaomao0055
站长QQ:14496453