Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yd-oss
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xingmin
yd-oss
Commits
6f8d3b2a
Commit
6f8d3b2a
authored
Sep 26, 2025
by
zhangxingmin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
通用Excel导入接口
parent
2baef10c
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
478 additions
and
0 deletions
+478
-0
yd-oss-api/src/main/java/com/yd/oss/api/controller/ApiExcelController.java
+25
-0
yd-oss-api/src/main/java/com/yd/oss/api/service/ApiExcelService.java
+6
-0
yd-oss-api/src/main/java/com/yd/oss/api/service/impl/ApiExcelServiceImpl.java
+39
-0
yd-oss-feign/src/main/java/com/yd/oss/feign/client/ApiExcelFeignClient.java
+28
-0
yd-oss-feign/src/main/java/com/yd/oss/feign/fallback/ApiExcelFeignFallbackFactory.java
+12
-0
yd-oss-feign/src/main/java/com/yd/oss/feign/result/ImportResult.java
+82
-0
yd-oss-feign/src/main/java/com/yd/oss/feign/result/ValidationResult.java
+44
-0
yd-oss-service/src/main/java/com/yd/oss/service/service/ExcelImportService.java
+18
-0
yd-oss-service/src/main/java/com/yd/oss/service/service/impl/ExcelImportServiceImpl.java
+224
-0
No files found.
yd-oss-api/src/main/java/com/yd/oss/api/controller/ApiExcelController.java
View file @
6f8d3b2a
...
...
@@ -6,6 +6,7 @@ import com.yd.oss.feign.client.ApiExcelFeignClient;
import
com.yd.oss.feign.request.ApiOssExportAppointmentExcelRequest
;
import
com.yd.oss.feign.response.ApiOssExcelParseResponse
;
import
com.yd.oss.feign.response.ApiOssExportAppointmentExcelResponse
;
import
com.yd.oss.feign.result.ImportResult
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.RequestMapping
;
...
...
@@ -47,4 +48,28 @@ public class ApiExcelController implements ApiExcelFeignClient {
return
apiExcelService
.
parse
(
file
,
sheetClassNames
);
}
/**
* 通用Excel导入接口
* @param file Excel文件
* @param headerRow 表头行号(默认第1行,从0开始)
* @param dataStartRow 数据开始行号(默认第2行,从0开始)
* @param requiredFields 必填字段列表(多个字段逗号分隔)
* @return 导入的结果
*/
@Override
public
Result
<
ImportResult
>
importExcel
(
MultipartFile
file
,
Integer
headerRow
,
Integer
dataStartRow
,
String
requiredFields
)
{
return
apiExcelService
.
importExcel
(
file
,
headerRow
,
dataStartRow
,
requiredFields
);
}
/**
* 简化导入接口
* @param file
* @return
*/
@Override
public
Result
<
ImportResult
>
simpleImport
(
MultipartFile
file
)
{
return
apiExcelService
.
simpleImport
(
file
);
}
}
yd-oss-api/src/main/java/com/yd/oss/api/service/ApiExcelService.java
View file @
6f8d3b2a
...
...
@@ -4,6 +4,7 @@ import com.yd.common.result.Result;
import
com.yd.oss.feign.request.ApiOssExportAppointmentExcelRequest
;
import
com.yd.oss.feign.response.ApiOssExcelParseResponse
;
import
com.yd.oss.feign.response.ApiOssExportAppointmentExcelResponse
;
import
com.yd.oss.feign.result.ImportResult
;
import
org.springframework.web.multipart.MultipartFile
;
public
interface
ApiExcelService
{
...
...
@@ -11,4 +12,9 @@ public interface ApiExcelService {
Result
<
ApiOssExportAppointmentExcelResponse
>
exportAppointment
(
ApiOssExportAppointmentExcelRequest
request
);
Result
<
ApiOssExcelParseResponse
>
parse
(
MultipartFile
file
,
String
[]
sheetClassNames
);
Result
<
ImportResult
>
importExcel
(
MultipartFile
file
,
Integer
headerRow
,
Integer
dataStartRow
,
String
requiredFields
);
Result
<
ImportResult
>
simpleImport
(
MultipartFile
file
);
}
yd-oss-api/src/main/java/com/yd/oss/api/service/impl/ApiExcelServiceImpl.java
View file @
6f8d3b2a
...
...
@@ -6,12 +6,17 @@ import com.yd.oss.api.service.ApiExcelService;
import
com.yd.oss.feign.request.ApiOssExportAppointmentExcelRequest
;
import
com.yd.oss.feign.response.ApiOssExcelParseResponse
;
import
com.yd.oss.feign.response.ApiOssExportAppointmentExcelResponse
;
import
com.yd.oss.feign.result.ImportResult
;
import
com.yd.oss.service.service.AppointmentExcelService
;
import
com.yd.oss.service.service.ExcelImportService
;
import
com.yd.oss.service.service.ExcelParserService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.web.multipart.MultipartFile
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.Map
;
@Slf4j
...
...
@@ -24,6 +29,9 @@ public class ApiExcelServiceImpl implements ApiExcelService {
@Autowired
private
ExcelParserService
excelParserService
;
@Autowired
private
ExcelImportService
excelImportService
;
/**
* 导出excel-预约信息
* @param request
...
...
@@ -65,4 +73,35 @@ public class ApiExcelServiceImpl implements ApiExcelService {
}
}
/**
* 通用Excel导入接口
* @param file Excel文件
* @param headerRow 表头行号(默认第1行,从0开始)
* @param dataStartRow 数据开始行号(默认第2行,从0开始)
* @param requiredFields 必填字段列表(多个字段逗号分隔)
* @return 导入的结果
*/
@Override
public
Result
<
ImportResult
>
importExcel
(
MultipartFile
file
,
Integer
headerRow
,
Integer
dataStartRow
,
String
requiredFields
)
{
List
<
String
>
requiredFieldList
=
null
;
if
(
requiredFields
!=
null
&&
!
requiredFields
.
isEmpty
())
{
requiredFieldList
=
Arrays
.
asList
(
requiredFields
.
split
(
","
));
}
ImportResult
importResult
=
excelImportService
.
genericImport
(
file
,
headerRow
,
dataStartRow
,
requiredFieldList
);
return
Result
.
success
(
importResult
);
}
/**
* 简化导入接口
* @param file
* @return
*/
@Override
public
Result
<
ImportResult
>
simpleImport
(
MultipartFile
file
)
{
ImportResult
importResult
=
excelImportService
.
simpleImport
(
file
);
return
Result
.
success
(
importResult
);
}
}
yd-oss-feign/src/main/java/com/yd/oss/feign/client/ApiExcelFeignClient.java
View file @
6f8d3b2a
...
...
@@ -5,11 +5,13 @@ import com.yd.oss.feign.fallback.ApiExcelFeignFallbackFactory;
import
com.yd.oss.feign.request.ApiOssExportAppointmentExcelRequest
;
import
com.yd.oss.feign.response.ApiOssExcelParseResponse
;
import
com.yd.oss.feign.response.ApiOssExportAppointmentExcelResponse
;
import
com.yd.oss.feign.result.ImportResult
;
import
org.springframework.cloud.openfeign.FeignClient
;
import
org.springframework.http.MediaType
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.RequestPart
;
import
org.springframework.web.multipart.MultipartFile
;
...
...
@@ -21,6 +23,7 @@ public interface ApiExcelFeignClient {
/**
* 导出excel-预约信息
* @param request
* @return
*/
@PostMapping
(
"/export/appointment"
)
...
...
@@ -28,9 +31,34 @@ public interface ApiExcelFeignClient {
/**
* 通用-Excel解析(支持多sheet页解析)
* @param file
* @param sheetClassNames
* @return
*/
@PostMapping
(
value
=
"/parse-excel"
,
consumes
=
MediaType
.
MULTIPART_FORM_DATA_VALUE
)
Result
<
ApiOssExcelParseResponse
>
parse
(
@RequestPart
(
"file"
)
MultipartFile
file
,
@RequestPart
(
"sheetClassNames"
)
String
[]
sheetClassNames
);
/**
* 通用Excel导入接口
* @param file Excel文件
* @param headerRow 表头行号(默认第1行,从0开始)
* @param dataStartRow 数据开始行号(默认第2行,从0开始)
* @param requiredFields 必填字段列表(多个字段逗号分隔)
* @return 导入的结果
*/
@PostMapping
(
"/import"
)
Result
<
ImportResult
>
importExcel
(
@RequestParam
(
"file"
)
MultipartFile
file
,
@RequestParam
(
value
=
"headerRow"
,
required
=
false
)
Integer
headerRow
,
@RequestParam
(
value
=
"dataStartRow"
,
required
=
false
)
Integer
dataStartRow
,
@RequestParam
(
value
=
"requiredFields"
,
required
=
false
)
String
requiredFields
);
/**
* 简化导入接口
* @param file
* @return
*/
@PostMapping
(
"/simple-import"
)
Result
<
ImportResult
>
simpleImport
(
@RequestParam
(
"file"
)
MultipartFile
file
);
}
yd-oss-feign/src/main/java/com/yd/oss/feign/fallback/ApiExcelFeignFallbackFactory.java
View file @
6f8d3b2a
...
...
@@ -6,6 +6,7 @@ import com.yd.oss.feign.request.ApiOssExcelParseRequest;
import
com.yd.oss.feign.request.ApiOssExportAppointmentExcelRequest
;
import
com.yd.oss.feign.response.ApiOssExcelParseResponse
;
import
com.yd.oss.feign.response.ApiOssExportAppointmentExcelResponse
;
import
com.yd.oss.feign.result.ImportResult
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.cloud.openfeign.FallbackFactory
;
import
org.springframework.stereotype.Component
;
...
...
@@ -30,6 +31,17 @@ public class ApiExcelFeignFallbackFactory implements FallbackFactory<ApiExcelFei
return
null
;
}
@Override
public
Result
<
ImportResult
>
importExcel
(
MultipartFile
file
,
Integer
headerRow
,
Integer
dataStartRow
,
String
requiredFields
)
{
return
null
;
}
@Override
public
Result
<
ImportResult
>
simpleImport
(
MultipartFile
file
)
{
return
null
;
}
};
}
}
yd-oss-feign/src/main/java/com/yd/oss/feign/result/ImportResult.java
0 → 100644
View file @
6f8d3b2a
package
com
.
yd
.
oss
.
feign
.
result
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
/**
* 导入结果
*/
public
class
ImportResult
{
private
boolean
success
;
private
String
message
;
private
boolean
valid
;
private
int
totalCount
;
private
List
<
String
>
headers
;
private
List
<
Map
<
String
,
Object
>>
data
;
private
List
<
String
>
errorMessages
;
public
ImportResult
()
{
this
.
headers
=
new
ArrayList
<>();
this
.
data
=
new
ArrayList
<>();
this
.
errorMessages
=
new
ArrayList
<>();
}
// getter和setter方法
public
boolean
isSuccess
()
{
return
success
;
}
public
void
setSuccess
(
boolean
success
)
{
this
.
success
=
success
;
}
public
String
getMessage
()
{
return
message
;
}
public
void
setMessage
(
String
message
)
{
this
.
message
=
message
;
}
public
boolean
isValid
()
{
return
valid
;
}
public
void
setValid
(
boolean
valid
)
{
this
.
valid
=
valid
;
}
public
int
getTotalCount
()
{
return
totalCount
;
}
public
void
setTotalCount
(
int
totalCount
)
{
this
.
totalCount
=
totalCount
;
}
public
List
<
String
>
getHeaders
()
{
return
headers
;
}
public
void
setHeaders
(
List
<
String
>
headers
)
{
this
.
headers
=
headers
;
}
public
List
<
Map
<
String
,
Object
>>
getData
()
{
return
data
;
}
public
void
setData
(
List
<
Map
<
String
,
Object
>>
data
)
{
this
.
data
=
data
;
}
public
List
<
String
>
getErrorMessages
()
{
return
errorMessages
;
}
public
void
setErrorMessages
(
List
<
String
>
errorMessages
)
{
this
.
errorMessages
=
errorMessages
;
}
}
\ No newline at end of file
yd-oss-feign/src/main/java/com/yd/oss/feign/result/ValidationResult.java
0 → 100644
View file @
6f8d3b2a
package
com
.
yd
.
oss
.
feign
.
result
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* 数据验证结果
*/
public
class
ValidationResult
{
private
boolean
valid
;
private
List
<
String
>
errors
;
public
ValidationResult
()
{
this
.
errors
=
new
ArrayList
<>();
this
.
valid
=
true
;
}
// getter和setter方法
public
boolean
isValid
()
{
return
valid
;
}
public
void
setValid
(
boolean
valid
)
{
this
.
valid
=
valid
;
}
public
List
<
String
>
getErrors
()
{
return
errors
;
}
public
void
setErrors
(
List
<
String
>
errors
)
{
this
.
errors
=
errors
;
}
public
void
addError
(
String
error
)
{
this
.
errors
.
add
(
error
);
this
.
valid
=
false
;
}
public
String
getErrorMsg
()
{
return
String
.
join
(
"; "
,
errors
);
}
}
\ No newline at end of file
yd-oss-service/src/main/java/com/yd/oss/service/service/ExcelImportService.java
0 → 100644
View file @
6f8d3b2a
package
com
.
yd
.
oss
.
service
.
service
;
import
com.yd.oss.feign.result.ImportResult
;
import
org.springframework.web.multipart.MultipartFile
;
import
java.util.List
;
public
interface
ExcelImportService
{
ImportResult
genericImport
(
MultipartFile
file
,
Integer
headerRow
,
Integer
dataStartRow
,
List
<
String
>
requiredFields
);
ImportResult
simpleImport
(
MultipartFile
file
);
}
yd-oss-service/src/main/java/com/yd/oss/service/service/impl/ExcelImportServiceImpl.java
0 → 100644
View file @
6f8d3b2a
package
com
.
yd
.
oss
.
service
.
service
.
impl
;
import
cn.afterturn.easypoi.excel.ExcelImportUtil
;
import
cn.afterturn.easypoi.excel.entity.ImportParams
;
import
cn.afterturn.easypoi.excel.entity.result.ExcelImportResult
;
import
com.yd.oss.feign.result.ImportResult
;
import
com.yd.oss.feign.result.ValidationResult
;
import
com.yd.oss.service.service.ExcelImportService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.poi.ss.usermodel.*
;
import
org.springframework.stereotype.Service
;
import
org.springframework.web.multipart.MultipartFile
;
import
java.util.*
;
/**
* 通用Excel导入工具类
* 支持动态表头解析
*/
@Slf4j
@Service
public
class
ExcelImportServiceImpl
implements
ExcelImportService
{
/**
* 通用Excel导入
* @param file Excel文件
* @param headerRow 表头行号(默认第1行,从0开始)
* @param dataStartRow 数据开始行号(默认第2行,从0开始)
* @param requiredFields 必填字段列表
* @return 导入结果
*/
@Override
public
ImportResult
genericImport
(
MultipartFile
file
,
Integer
headerRow
,
Integer
dataStartRow
,
List
<
String
>
requiredFields
)
{
ImportResult
result
=
new
ImportResult
();
try
{
// 参数默认值处理
int
headerRowNum
=
headerRow
!=
null
?
headerRow
:
0
;
int
dataStartRowNum
=
dataStartRow
!=
null
?
dataStartRow
:
1
;
// 1. 获取表头信息
List
<
String
>
headers
=
getExcelHeaders
(
file
,
headerRowNum
);
result
.
setHeaders
(
headers
);
// 2. 导入Excel数据
ExcelImportResult
<
Map
<
String
,
Object
>>
importResult
=
importExcel
(
file
,
headerRowNum
,
dataStartRowNum
);
// 3. 处理导入结果
List
<
Map
<
String
,
Object
>>
data
=
processImportResult
(
importResult
,
headers
);
result
.
setData
(
data
);
result
.
setTotalCount
(
data
.
size
());
// 4. 数据验证
if
(
requiredFields
!=
null
&&
!
requiredFields
.
isEmpty
())
{
ValidationResult
validationResult
=
validateData
(
data
,
requiredFields
);
result
.
setValid
(
validationResult
.
isValid
());
result
.
setErrorMessages
(
validationResult
.
getErrors
());
}
else
{
result
.
setValid
(
true
);
}
result
.
setSuccess
(
true
);
result
.
setMessage
(
"导入成功,共导入"
+
data
.
size
()
+
"条数据"
);
}
catch
(
Exception
e
)
{
result
.
setSuccess
(
false
);
result
.
setMessage
(
"导入失败:"
+
e
.
getMessage
());
}
return
result
;
}
/**
* 简化的导入方法(使用默认参数)
* @param file
* @return
*/
@Override
public
ImportResult
simpleImport
(
MultipartFile
file
)
{
return
genericImport
(
file
,
0
,
1
,
null
);
}
/**
* 通用Excel导入方法
* @param file Excel文件
* @param headerRowNum 表头所在行号(从0开始)
* @param dataStartRowNum 数据开始行号(从0开始)
* @return 导入结果
*/
public
static
ExcelImportResult
<
Map
<
String
,
Object
>>
importExcel
(
MultipartFile
file
,
int
headerRowNum
,
int
dataStartRowNum
)
throws
Exception
{
ImportParams
params
=
new
ImportParams
();
params
.
setHeadRows
(
headerRowNum
+
1
);
// 表头行数
params
.
setStartRows
(
dataStartRowNum
);
// 数据开始行
// 修正:方法名拼写错误,应该是setNeedVerify
params
.
setNeedVerify
(
true
);
// 需要校验
// 使用Map接收数据
return
ExcelImportUtil
.
importExcelMore
(
file
.
getInputStream
(),
Map
.
class
,
params
);
}
/**
* 获取Excel表头信息
* @param file Excel文件
* @param headerRowNum 表头所在行号(从0开始)
* @return 表头字段列表
*/
public
static
List
<
String
>
getExcelHeaders
(
MultipartFile
file
,
int
headerRowNum
)
throws
Exception
{
List
<
String
>
headers
=
new
ArrayList
<>();
// 修正:使用WorkbookFactory.create()静态方法
try
(
Workbook
workbook
=
WorkbookFactory
.
create
(
file
.
getInputStream
()))
{
Sheet
sheet
=
workbook
.
getSheetAt
(
0
);
Row
headerRow
=
sheet
.
getRow
(
headerRowNum
);
if
(
headerRow
!=
null
)
{
for
(
Cell
cell
:
headerRow
)
{
String
headerValue
=
getCellValue
(
cell
);
if
(
headerValue
!=
null
&&
!
headerValue
.
trim
().
isEmpty
())
{
headers
.
add
(
headerValue
.
trim
());
}
}
}
}
return
headers
;
}
/**
* 获取单元格值
* @param cell
* @return
*/
public
static
String
getCellValue
(
Cell
cell
)
{
if
(
cell
==
null
)
{
return
null
;
}
switch
(
cell
.
getCellType
())
{
case
STRING:
return
cell
.
getStringCellValue
();
case
NUMERIC:
return
String
.
valueOf
(
cell
.
getNumericCellValue
());
case
BOOLEAN:
return
String
.
valueOf
(
cell
.
getBooleanCellValue
());
case
FORMULA:
return
cell
.
getCellFormula
();
default
:
return
""
;
}
}
/**
* 处理导入结果,转换为更友好的数据结构
* @param result 导入结果
* @param headers 表头信息
* @return 处理后的数据
*/
public
static
List
<
Map
<
String
,
Object
>>
processImportResult
(
ExcelImportResult
<
Map
<
String
,
Object
>>
result
,
List
<
String
>
headers
)
{
List
<
Map
<
String
,
Object
>>
processedData
=
new
ArrayList
<>();
if
(
result
!=
null
&&
result
.
getList
()
!=
null
)
{
for
(
Map
<
String
,
Object
>
rowData
:
result
.
getList
())
{
Map
<
String
,
Object
>
processedRow
=
new
LinkedHashMap
<>();
// 按照表头顺序重新组织数据
for
(
String
header
:
headers
)
{
processedRow
.
put
(
header
,
rowData
.
get
(
header
));
}
processedData
.
add
(
processedRow
);
}
}
return
processedData
;
}
/**
* 验证导入数据
* @param data 导入的数据
* @param requiredFields 必填字段
* @return 验证结果
*/
public
static
ValidationResult
validateData
(
List
<
Map
<
String
,
Object
>>
data
,
List
<
String
>
requiredFields
)
{
ValidationResult
result
=
new
ValidationResult
();
result
.
setValid
(
true
);
for
(
int
i
=
0
;
i
<
data
.
size
();
i
++)
{
Map
<
String
,
Object
>
row
=
data
.
get
(
i
);
int
rowNum
=
i
+
1
;
// 实际行号(从1开始)
// 检查必填字段
for
(
String
field
:
requiredFields
)
{
Object
value
=
row
.
get
(
field
);
if
(
value
==
null
||
value
.
toString
().
trim
().
isEmpty
())
{
result
.
setValid
(
false
);
result
.
getErrors
().
add
(
"第"
+
rowNum
+
"行,字段["
+
field
+
"]不能为空"
);
}
}
// 这里可以添加更多的验证规则
// 例如:数据类型验证、格式验证等
}
return
result
;
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment