Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
J
jy_jfb
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Administrator
jy_jfb
Commits
306fdcac
提交
306fdcac
authored
1月 13, 2026
作者:
wangmenglong
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
增加爬虫
上级
c645045d
隐藏空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
450 行增加
和
4 行删除
+450
-4
ImportRecruitController.java
...m/jfb/recruit/controller/api/ImportRecruitController.java
+164
-4
ExcelAppendUtil.java
...java/com/jfb/recruit/util/Excelutils/ExcelAppendUtil.java
+116
-0
JobsExcel.java
.../main/java/com/jfb/recruit/util/Excelutils/JobsExcel.java
+30
-0
OrgExcel.java
...c/main/java/com/jfb/recruit/util/Excelutils/OrgExcel.java
+25
-0
OrgExcelAppendUtil.java
...a/com/jfb/recruit/util/Excelutils/OrgExcelAppendUtil.java
+115
-0
没有找到文件。
jfb-recruit/src/main/java/com/jfb/recruit/controller/api/ImportRecruitController.java
浏览文件 @
306fdcac
...
@@ -4,11 +4,12 @@ import base.controller.BaseController;
...
@@ -4,11 +4,12 @@ import base.controller.BaseController;
import
base.result.BaseResult
;
import
base.result.BaseResult
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
import
com.alibaba.fastjson.JSONObject
;
import
com.github.pagehelper.PageInfo
;
import
com.jfb.recruit.bean.auth.UserContext
;
import
com.jfb.recruit.service.OrgService
;
import
com.jfb.recruit.service.OrgService
;
import
com.jfb.recruit.service.RecruitService
;
import
com.jfb.recruit.service.RecruitService
;
import
com.jfb.recruit.util.auth.UserUtils
;
import
com.jfb.recruit.util.Excelutils.ExcelAppendUtil
;
import
com.jfb.recruit.util.Excelutils.JobsExcel
;
import
com.jfb.recruit.util.Excelutils.OrgExcel
;
import
com.jfb.recruit.util.Excelutils.OrgExcelAppendUtil
;
import
data.recruit.Org
;
import
data.recruit.Org
;
import
data.recruit.Recruit
;
import
data.recruit.Recruit
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
...
@@ -42,8 +43,167 @@ public class ImportRecruitController extends BaseController {
...
@@ -42,8 +43,167 @@ public class ImportRecruitController extends BaseController {
@Resource
@Resource
OrgService
orgService
;
OrgService
orgService
;
// 桌面的Excel文件名(可自定义,如:upload_record.xlsx)
private
static
final
String
EXCEL_FILE_NAME
=
"/pchongshuju/show.xlsx"
;
private
static
final
String
EXCEL_FILE_ORG_NAME
=
"/pchongshuju/showOrg.xlsx"
;
/**
* 文件上传接口
* @param file 上传的文件
* @param remark 备注(可选,前端传)
* @return 上传结果
*/
@PostMapping
(
"/upload/job"
)
public
BaseResult
uploadFile
(
@RequestParam
(
"file"
)
MultipartFile
file
,
@RequestParam
(
value
=
"remark"
,
defaultValue
=
"无备注"
)
String
remark
)
{
// 1. 校验文件是否为空
if
(
file
.
isEmpty
())
{
return
BaseResult
.
error
(
"001"
);
}
// 2. 校验文件类型(增强严谨性,避免OOXML错误)
String
originalFilename
=
file
.
getOriginalFilename
();
// 优化:双重校验(后缀+内容类型,防止改后缀的非JSON文件)
if
(
originalFilename
==
null
||
!
originalFilename
.
trim
().
toLowerCase
().
endsWith
(
".json"
))
{
return
BaseResult
.
error
(
"002"
);
}
// 可选:额外校验Content-Type,进一步防止非JSON文件
String
contentType
=
file
.
getContentType
();
if
(
contentType
!=
null
&&
!
contentType
.
equalsIgnoreCase
(
"application/json"
)
&&
!
contentType
.
equalsIgnoreCase
(
"text/plain"
))
{
return
BaseResult
.
error
(
"002"
);
}
// 3. 读取文件全部内容(确保流仅用于文本读取,避免被Office解析库误处理)
StringBuilder
jsonContent
=
new
StringBuilder
();
// 核心:仅用BufferedReader读取文本,不引入任何Office解析逻辑
try
(
BufferedReader
reader
=
new
BufferedReader
(
new
InputStreamReader
(
file
.
getInputStream
(),
StandardCharsets
.
UTF_8
)
// 强制UTF-8,避免乱码
))
{
String
line
;
while
((
line
=
reader
.
readLine
())
!=
null
)
{
jsonContent
.
append
(
line
);
}
JSONArray
jsonArray
=
JSONArray
.
parseArray
(
jsonContent
.
toString
());
// 3. 调用工具类追加数据(EasyExcel支持批量,这里单条也用列表)
List
<
JobsExcel
>
dataList
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
jsonArray
.
size
();
i
++)
{
JSONObject
jsonObject
=
jsonArray
.
getJSONObject
(
i
);
// 2. 封装要追加到Excel的数据
JobsExcel
jobsExcel
=
new
JobsExcel
();
jobsExcel
.
setJonName
(
jsonObject
.
getString
(
"jobName"
));
jobsExcel
.
setFullCompanyName
(
jsonObject
.
getString
(
"fullCompanyName"
));
jobsExcel
.
setJobSalaryMin
(
jsonObject
.
getString
(
"jobSalaryMin"
));
jobsExcel
.
setJobSalaryMax
(
jsonObject
.
getString
(
"jobSalaryMax"
));
jobsExcel
.
setJobDescribe
(
jsonObject
.
getString
(
"jobDescribe"
));
dataList
.
add
(
jobsExcel
);
}
ExcelAppendUtil
.
appendDataToExcel
(
EXCEL_FILE_NAME
,
dataList
);
// 4. 返回成功响应
return
BaseResult
.
success
();
// 优化:确保返回字符串类型
}
catch
(
IOException
e
)
{
return
BaseResult
.
error
(
"003"
);
}
}
/**
* 文件上传接口
* @param file 上传的文件
* @param remark 备注(可选,前端传)
* @return 上传结果
*/
@PostMapping
(
"/upload/org"
)
public
BaseResult
uploadFileOrg
(
@RequestParam
(
"file"
)
MultipartFile
file
,
@RequestParam
(
value
=
"remark"
,
defaultValue
=
"无备注"
)
String
remark
)
{
// 1. 校验文件是否为空
if
(
file
.
isEmpty
())
{
return
BaseResult
.
error
(
"001"
);
}
// 2. 校验文件类型(增强严谨性,避免OOXML错误)
String
originalFilename
=
file
.
getOriginalFilename
();
// 优化:双重校验(后缀+内容类型,防止改后缀的非JSON文件)
if
(
originalFilename
==
null
||
!
originalFilename
.
trim
().
toLowerCase
().
endsWith
(
".json"
))
{
return
BaseResult
.
error
(
"002"
);
}
// 可选:额外校验Content-Type,进一步防止非JSON文件
String
contentType
=
file
.
getContentType
();
if
(
contentType
!=
null
&&
!
contentType
.
equalsIgnoreCase
(
"application/json"
)
&&
!
contentType
.
equalsIgnoreCase
(
"text/plain"
))
{
return
BaseResult
.
error
(
"002"
);
}
// 3. 读取文件全部内容(确保流仅用于文本读取,避免被Office解析库误处理)
StringBuilder
jsonContent
=
new
StringBuilder
();
// 核心:仅用BufferedReader读取文本,不引入任何Office解析逻辑
try
(
BufferedReader
reader
=
new
BufferedReader
(
new
InputStreamReader
(
file
.
getInputStream
(),
StandardCharsets
.
UTF_8
)
// 强制UTF-8,避免乱码
))
{
String
line
;
while
((
line
=
reader
.
readLine
())
!=
null
)
{
jsonContent
.
append
(
line
);
}
JSONArray
jsonArray
=
JSONArray
.
parseArray
(
jsonContent
.
toString
());
// 3. 调用工具类追加数据(EasyExcel支持批量,这里单条也用列表)
List
<
OrgExcel
>
dataList
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
jsonArray
.
size
();
i
++)
{
JSONObject
jsonObject
=
jsonArray
.
getJSONObject
(
i
);
// 2. 封装要追加到Excel的数据
OrgExcel
jobsExcel
=
new
OrgExcel
();
jobsExcel
.
setName
(
jsonObject
.
getString
(
"name"
));
jobsExcel
.
setIntro
(
jsonObject
.
getString
(
"intro"
));
jobsExcel
.
setAddress
(
jsonObject
.
getString
(
"address"
));
dataList
.
add
(
jobsExcel
);
}
OrgExcelAppendUtil
.
appendDataToExcel
(
EXCEL_FILE_ORG_NAME
,
dataList
);
// 4. 返回成功响应
return
BaseResult
.
success
();
// 优化:确保返回字符串类型
}
catch
(
IOException
e
)
{
return
BaseResult
.
error
(
"003"
);
}
}
/**
/**
* 获取企业
信息
* 获取企业
url
* @return: base.result.BaseResult
* @return: base.result.BaseResult
* @Author: wml
* @Author: wml
* @Date 2026/1/12 15:33
* @Date 2026/1/12 15:33
...
...
jfb-recruit/src/main/java/com/jfb/recruit/util/Excelutils/ExcelAppendUtil.java
0 → 100644
浏览文件 @
306fdcac
package
com
.
jfb
.
recruit
.
util
.
Excelutils
;
import
com.alibaba.excel.EasyExcel
;
import
com.alibaba.excel.context.AnalysisContext
;
import
com.alibaba.excel.event.AnalysisEventListener
;
import
com.jfb.recruit.util.Excelutils.JobsExcel
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* 适配EasyExcel 2.2.10 + POI 3.17的Excel追加工具类(彻底解决空文件+覆盖问题)
*/
public
class
ExcelAppendUtil
{
// 获取桌面Excel路径
public
static
String
getDesktopExcelPath
(
String
excelFileName
)
{
String
desktopPath
=
System
.
getProperty
(
"user.home"
)
+
File
.
separator
+
"Desktop"
;
return
desktopPath
+
File
.
separator
+
excelFileName
;
}
// 读取Excel中所有已有数据(2.2.10兼容写法)
private
static
List
<
JobsExcel
>
readAllExcelData
(
String
excelPath
)
{
File
excelFile
=
new
File
(
excelPath
);
// 空文件/不存在直接返回空列表
if
(!
excelFile
.
exists
()
||
excelFile
.
length
()
==
0
)
{
return
new
ArrayList
<>();
}
// 自定义监听器读取所有数据
class
DataReadListener
extends
AnalysisEventListener
<
JobsExcel
>
{
private
List
<
JobsExcel
>
dataList
=
new
ArrayList
<>();
@Override
public
void
invoke
(
JobsExcel
data
,
AnalysisContext
context
)
{
dataList
.
add
(
data
);
}
@Override
public
void
doAfterAllAnalysed
(
AnalysisContext
context
)
{}
public
List
<
JobsExcel
>
getDataList
()
{
return
dataList
;
}
}
DataReadListener
listener
=
new
DataReadListener
();
try
{
EasyExcel
.
read
(
excelPath
,
JobsExcel
.
class
,
listener
)
.
sheet
(
"上传记录"
)
.
doRead
();
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"读取Excel数据失败,将重新创建文件:"
+
e
.
getMessage
());
return
new
ArrayList
<>();
}
return
listener
.
getDataList
();
}
// 核心:追加数据(2.2.10兼容,零覆盖+空文件修复)
public
static
void
appendDataToExcel
(
String
excelFileName
,
List
<
JobsExcel
>
newData
)
{
String
excelPath
=
getDesktopExcelPath
(
excelFileName
);
File
excelFile
=
new
File
(
excelPath
);
// ========== 第一步:最前置的空文件检测(关键!拦截所有空文件场景) ==========
if
(
excelFile
.
exists
())
{
// 1. 空文件直接删除,避免POI解析报错
if
(
excelFile
.
length
()
==
0
)
{
excelFile
.
delete
();
System
.
out
.
println
(
"检测到空Excel文件,已删除:"
+
excelPath
);
}
// 2. 非空文件但读取失败(损坏),也删除
else
{
try
{
// 尝试读取文件头,验证文件有效性
EasyExcel
.
read
(
excelPath
).
sheet
(
"上传记录"
).
doRead
();
}
catch
(
Exception
e
)
{
excelFile
.
delete
();
System
.
out
.
println
(
"Excel文件损坏,已删除:"
+
e
.
getMessage
());
}
}
}
try
{
// ========== 第二步:读取原有数据 + 合并新数据 ==========
List
<
JobsExcel
>
allData
=
new
ArrayList
<>();
// 文件存在且有效:读取原有数据
if
(
excelFile
.
exists
()
&&
excelFile
.
length
()
>
0
)
{
allData
=
readAllExcelData
(
excelPath
);
System
.
out
.
println
(
"读取到原有Excel数据行数:"
+
allData
.
size
());
}
// 合并新数据(核心:追加=原有数据+新数据)
allData
.
addAll
(
newData
);
// ========== 第三步:重新写入(覆盖整个文件,但数据是合并后的,等价于追加) ==========
EasyExcel
.
write
(
excelPath
,
JobsExcel
.
class
)
.
sheet
(
"上传记录"
)
.
doWrite
(
allData
);
// ========== 第四步:验证写入结果,避免生成空文件 ==========
if
(!
excelFile
.
exists
()
||
excelFile
.
length
()
==
0
)
{
throw
new
RuntimeException
(
"写入Excel失败:生成了空文件(桌面权限不足/文件被占用)"
);
}
System
.
out
.
println
(
"数据追加成功!总数据行数:"
+
allData
.
size
()
+
",文件路径:"
+
excelPath
);
}
catch
(
Exception
e
)
{
// 异常时清理空文件
if
(
excelFile
.
exists
()
&&
excelFile
.
length
()
==
0
)
{
excelFile
.
delete
();
}
throw
new
RuntimeException
(
"追加Excel数据失败:"
+
e
.
getMessage
(),
e
);
}
}
}
\ No newline at end of file
jfb-recruit/src/main/java/com/jfb/recruit/util/Excelutils/JobsExcel.java
0 → 100644
浏览文件 @
306fdcac
package
com
.
jfb
.
recruit
.
util
.
Excelutils
;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
lombok.Data
;
/**
* @ClassName : JobsExcel
* @Description :
* @Author : wml
* @Date: 2026-01-13 16:01
*/
@Data
public
class
JobsExcel
{
// ExcelProperty:指定列名,index指定列索引(0开始)
@ExcelProperty
(
value
=
"职位名"
,
index
=
0
)
private
String
jonName
;
@ExcelProperty
(
value
=
"企业名"
,
index
=
1
)
private
String
fullCompanyName
;
@ExcelProperty
(
value
=
"薪资范围"
,
index
=
2
)
private
String
jobSalaryMin
;
@ExcelProperty
(
value
=
"薪资范围"
,
index
=
3
)
private
String
jobSalaryMax
;
@ExcelProperty
(
value
=
"工作内容"
,
index
=
4
)
private
String
jobDescribe
;
}
jfb-recruit/src/main/java/com/jfb/recruit/util/Excelutils/OrgExcel.java
0 → 100644
浏览文件 @
306fdcac
package
com
.
jfb
.
recruit
.
util
.
Excelutils
;
import
com.alibaba.excel.annotation.ExcelProperty
;
import
lombok.Data
;
/**
* @ClassName : JobsExcel
* @Description :
* @Author : wml
* @Date: 2026-01-13 16:01
*/
@Data
public
class
OrgExcel
{
// ExcelProperty:指定列名,index指定列索引(0开始)
@ExcelProperty
(
value
=
"企业名"
,
index
=
0
)
private
String
name
;
@ExcelProperty
(
value
=
"地址"
,
index
=
1
)
private
String
address
;
@ExcelProperty
(
value
=
"企业简介"
,
index
=
2
)
private
String
intro
;
}
jfb-recruit/src/main/java/com/jfb/recruit/util/Excelutils/OrgExcelAppendUtil.java
0 → 100644
浏览文件 @
306fdcac
package
com
.
jfb
.
recruit
.
util
.
Excelutils
;
import
com.alibaba.excel.EasyExcel
;
import
com.alibaba.excel.context.AnalysisContext
;
import
com.alibaba.excel.event.AnalysisEventListener
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* 适配EasyExcel 2.2.10 + POI 3.17的Excel追加工具类(彻底解决空文件+覆盖问题)
*/
public
class
OrgExcelAppendUtil
{
// 获取桌面Excel路径
public
static
String
getDesktopExcelPath
(
String
excelFileName
)
{
String
desktopPath
=
System
.
getProperty
(
"user.home"
)
+
File
.
separator
+
"Desktop"
;
return
desktopPath
+
File
.
separator
+
excelFileName
;
}
// 读取Excel中所有已有数据(2.2.10兼容写法)
private
static
List
<
OrgExcel
>
readAllExcelData
(
String
excelPath
)
{
File
excelFile
=
new
File
(
excelPath
);
// 空文件/不存在直接返回空列表
if
(!
excelFile
.
exists
()
||
excelFile
.
length
()
==
0
)
{
return
new
ArrayList
<>();
}
// 自定义监听器读取所有数据
class
DataReadListener
extends
AnalysisEventListener
<
OrgExcel
>
{
private
List
<
OrgExcel
>
dataList
=
new
ArrayList
<>();
@Override
public
void
invoke
(
OrgExcel
data
,
AnalysisContext
context
)
{
dataList
.
add
(
data
);
}
@Override
public
void
doAfterAllAnalysed
(
AnalysisContext
context
)
{}
public
List
<
OrgExcel
>
getDataList
()
{
return
dataList
;
}
}
DataReadListener
listener
=
new
DataReadListener
();
try
{
EasyExcel
.
read
(
excelPath
,
OrgExcel
.
class
,
listener
)
.
sheet
(
"上传记录"
)
.
doRead
();
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"读取Excel数据失败,将重新创建文件:"
+
e
.
getMessage
());
return
new
ArrayList
<>();
}
return
listener
.
getDataList
();
}
// 核心:追加数据(2.2.10兼容,零覆盖+空文件修复)
public
static
void
appendDataToExcel
(
String
excelFileName
,
List
<
OrgExcel
>
newData
)
{
String
excelPath
=
getDesktopExcelPath
(
excelFileName
);
File
excelFile
=
new
File
(
excelPath
);
// ========== 第一步:最前置的空文件检测(关键!拦截所有空文件场景) ==========
if
(
excelFile
.
exists
())
{
// 1. 空文件直接删除,避免POI解析报错
if
(
excelFile
.
length
()
==
0
)
{
excelFile
.
delete
();
System
.
out
.
println
(
"检测到空Excel文件,已删除:"
+
excelPath
);
}
// 2. 非空文件但读取失败(损坏),也删除
else
{
try
{
// 尝试读取文件头,验证文件有效性
EasyExcel
.
read
(
excelPath
).
sheet
(
"上传记录"
).
doRead
();
}
catch
(
Exception
e
)
{
excelFile
.
delete
();
System
.
out
.
println
(
"Excel文件损坏,已删除:"
+
e
.
getMessage
());
}
}
}
try
{
// ========== 第二步:读取原有数据 + 合并新数据 ==========
List
<
OrgExcel
>
allData
=
new
ArrayList
<>();
// 文件存在且有效:读取原有数据
if
(
excelFile
.
exists
()
&&
excelFile
.
length
()
>
0
)
{
allData
=
readAllExcelData
(
excelPath
);
System
.
out
.
println
(
"读取到原有Excel数据行数:"
+
allData
.
size
());
}
// 合并新数据(核心:追加=原有数据+新数据)
allData
.
addAll
(
newData
);
// ========== 第三步:重新写入(覆盖整个文件,但数据是合并后的,等价于追加) ==========
EasyExcel
.
write
(
excelPath
,
OrgExcel
.
class
)
.
sheet
(
"上传记录"
)
.
doWrite
(
allData
);
// ========== 第四步:验证写入结果,避免生成空文件 ==========
if
(!
excelFile
.
exists
()
||
excelFile
.
length
()
==
0
)
{
throw
new
RuntimeException
(
"写入Excel失败:生成了空文件(桌面权限不足/文件被占用)"
);
}
System
.
out
.
println
(
"数据追加成功!总数据行数:"
+
allData
.
size
()
+
",文件路径:"
+
excelPath
);
}
catch
(
Exception
e
)
{
// 异常时清理空文件
if
(
excelFile
.
exists
()
&&
excelFile
.
length
()
==
0
)
{
excelFile
.
delete
();
}
throw
new
RuntimeException
(
"追加Excel数据失败:"
+
e
.
getMessage
(),
e
);
}
}
}
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论