Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
W
wangxiaolu-export
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
promotion
wangxiaolu-export
Commits
cdac5cb8
提交
cdac5cb8
authored
7月 03, 2024
作者:
李秋林
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
1、导出促销员上报数据;2、dockerfile文件
上级
cbe92da0
隐藏空白字符变更
内嵌
并排
正在显示
23 个修改的文件
包含
2012 行增加
和
9 行删除
+2012
-9
Dockerfile
Dockerfile
+13
-0
pom.xml
pom.xml
+160
-8
ExcelExport.java
...in/java/com/wangxiaolu/export/annotation/ExcelExport.java
+38
-0
ExcelImport.java
...in/java/com/wangxiaolu/export/annotation/ExcelImport.java
+42
-0
PromotionActivityExport.java
.../export/controller/promotion/PromotionActivityExport.java
+215
-0
TemporaryActivityClockMapper.java
...angxiaolu/export/mapper/TemporaryActivityClockMapper.java
+26
-0
TemporaryActivityPhotoMapper.java
...angxiaolu/export/mapper/TemporaryActivityPhotoMapper.java
+24
-0
TemporaryActivityReportedMapper.java
...xiaolu/export/mapper/TemporaryActivityReportedMapper.java
+28
-0
TemporaryActivityClockDO.java
...xiaolu/export/mapper/entity/TemporaryActivityClockDO.java
+25
-0
TemporaryActivityPhotoDO.java
...xiaolu/export/mapper/entity/TemporaryActivityPhotoDO.java
+43
-0
TemporaryActivityReportedDO.java
...olu/export/mapper/entity/TemporaryActivityReportedDO.java
+50
-0
ActivityVo.java
src/main/java/com/wangxiaolu/export/pojo/ActivityVo.java
+17
-0
PromotionActivityService.java
...m/wangxiaolu/export/service/PromotionActivityService.java
+29
-0
PromotionActivityServiceImpl.java
...olu/export/service/impl/PromotionActivityServiceImpl.java
+63
-0
ExcelClassField.java
...main/java/com/wangxiaolu/export/util/ExcelClassField.java
+89
-0
ExcelUtils.java
src/main/java/com/wangxiaolu/export/util/ExcelUtils.java
+1011
-0
application-dev.yml
src/main/resources/application-dev.yml
+19
-0
application-live.yml
src/main/resources/application-live.yml
+19
-0
application.properties
src/main/resources/application.properties
+0
-1
application.yml
src/main/resources/application.yml
+10
-0
TemporaryActivityClockMapper.xml
src/main/resources/mapper/TemporaryActivityClockMapper.xml
+29
-0
TemporaryActivityPhotoMapper.xml
src/main/resources/mapper/TemporaryActivityPhotoMapper.xml
+23
-0
TemporaryActivityReportedMapper.xml
...main/resources/mapper/TemporaryActivityReportedMapper.xml
+39
-0
没有找到文件。
Dockerfile
0 → 100644
浏览文件 @
cdac5cb8
FROM
openjdk:8
WORKDIR
/promotion
ADD
./target/wangxiaolu-export.jar /promotion/app.jar
#设置时区
RUN
ln
-sf
/usr/share/zoneinfo/Asia/Shanghai /etc/localtime
&&
echo
'Asia/Shanghai'
>
/etc/timezone
# 定义容器启动命令ENTRYPOINT 和 CMD指令类似,都可以用于增加启动参数
ENTRYPOINT
["nohup","java", "-jar", "/promotion/app.jar"]
CMD
["--spring.profiles.active=live"]
EXPOSE
8012
pom.xml
浏览文件 @
cdac5cb8
...
@@ -2,34 +2,186 @@
...
@@ -2,34 +2,186 @@
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
<project
xmlns=
"http://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
>
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<modelVersion>
4.0.0
</modelVersion>
<!-- 当前pom依赖在项目进行拆分时,拆到parent项目中,此项目做为promotion业务子模块-->
<parent>
<parent>
<groupId>
org.springframework.boot
</groupId>
<groupId>
com.wangxiaolu
</groupId>
<artifactId>
spring-boot-starter-parent
</artifactId>
<artifactId>
wangxiaolu-promotion-parent
</artifactId>
<version>
3.3.0
</version>
<version>
0.0.1
</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
</parent>
<groupId>
com.wangxiaolu
</groupId>
<groupId>
com.wangxiaolu
</groupId>
<artifactId>
wangxiaolu-export
</artifactId>
<artifactId>
wangxiaolu-export
</artifactId>
<version>
0.0.1-SNAPSHOT
</version>
<version>
0.0.1
</version>
<name>
wangxiaolu-export
</name>
<name>
wangxiaolu-export
</name>
<description>
wangxiaolu-export
</description>
<description>
wangxiaolu-export
</description>
<properties>
<java.version>
22
</java.version>
</properties>
<dependencies>
<dependencies>
<dependency>
<groupId>
com.wangxiaolu
</groupId>
<artifactId>
wangxiaolu-promotion-common
</artifactId>
<version>
0.0.1
</version>
<exclusions>
<exclusion>
<artifactId>
spring-cloud-gateway-server
</artifactId>
<groupId>
org.springframework.cloud
</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter
</artifactId>
<artifactId>
spring-boot-starter
</artifactId>
</dependency>
</dependency>
<dependency>
<groupId>
org.projectlombok
</groupId>
<artifactId>
lombok
</artifactId>
<optional>
true
</optional>
</dependency>
<dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-test
</artifactId>
<artifactId>
spring-boot-starter-test
</artifactId>
<scope>
test
</scope>
<scope>
test
</scope>
<exclusions>
<exclusion>
<artifactId>
slf4j-api
</artifactId>
<groupId>
org.slf4j
</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-validation
</artifactId>
</dependency>
<!-- Web 场景启动器) 来为 Web 开发予以支持。spring-boot-starter-web 为我们提供了嵌入的 Servlet 容器以及 SpringMVC 的依赖,并为 Spring MVC 提供了大量自动配置,可以适用于大多数 Web 开发场景。-->
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-web
</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-aop
</artifactId>
</dependency>
<dependency>
<groupId>
com.alibaba
</groupId>
<artifactId>
druid
</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>
mysql
</groupId>
<artifactId>
mysql-connector-java
</artifactId>
</dependency>
</dependency>
<dependency>
<groupId>
com.baomidou
</groupId>
<artifactId>
mybatis-plus-annotation
</artifactId>
<scope>
compile
</scope>
</dependency>
<dependency>
<groupId>
com.baomidou
</groupId>
<artifactId>
mybatis-plus-boot-starter
</artifactId>
<exclusions>
<exclusion>
<artifactId>
slf4j-api
</artifactId>
<groupId>
org.slf4j
</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>
com.alibaba
</groupId>
<artifactId>
fastjson
</artifactId>
</dependency>
<dependency>
<groupId>
cn.hutool
</groupId>
<artifactId>
hutool-all
</artifactId>
</dependency>
<dependency>
<groupId>
commons-codec
</groupId>
<artifactId>
commons-codec
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-data-redis
</artifactId>
<exclusions>
<exclusion>
<artifactId>
slf4j-api
</artifactId>
<groupId>
org.slf4j
</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>
redis.clients
</groupId>
<artifactId>
jedis
</artifactId>
<exclusions>
<exclusion>
<artifactId>
slf4j-api
</artifactId>
<groupId>
org.slf4j
</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 文件上传 -->
<dependency>
<groupId>
org.apache.httpcomponents
</groupId>
<artifactId>
httpmime
</artifactId>
<version>
4.5.7
</version>
</dependency>
<!-- JSON -->
<dependency>
<groupId>
com.alibaba
</groupId>
<artifactId>
fastjson
</artifactId>
<version>
1.2.41
</version>
</dependency>
<!-- POI -->
<dependency>
<groupId>
org.apache.poi
</groupId>
<artifactId>
poi-ooxml
</artifactId>
<version>
3.16
</version>
</dependency>
<dependency>
<groupId>
com.alibaba.cloud
</groupId>
<artifactId>
spring-cloud-starter-alibaba-nacos-discovery
</artifactId>
<exclusions>
<exclusion>
<artifactId>
commons-io
</artifactId>
<groupId>
commons-io
</groupId>
</exclusion>
<exclusion>
<artifactId>
guava
</artifactId>
<groupId>
com.google.guava
</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencies>
<build>
<build>
<finalName>
wangxiaolu-export
</finalName>
<plugins>
<plugins>
<plugin>
<plugin>
<groupId>
org.springframework.boot
</groupId>
<groupId>
org.springframework.boot
</groupId>
...
...
src/main/java/com/wangxiaolu/export/annotation/ExcelExport.java
0 → 100644
浏览文件 @
cdac5cb8
package
com
.
wangxiaolu
.
export
.
annotation
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* @author sunnyzyq
* @date 2021/12/17
*/
@Target
(
ElementType
.
FIELD
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
ExcelExport
{
/**
* 字段名称
*/
String
value
();
/**
* 导出排序先后: 数字越小越靠前(默认按Java类字段顺序导出)
*/
int
sort
()
default
0
;
/**
* 导出映射,格式如:0-未知;1-男;2-女
*/
String
kv
()
default
""
;
/**
* 导出模板示例值(有值的话,直接取该值,不做映射)
*/
String
example
()
default
""
;
}
\ No newline at end of file
src/main/java/com/wangxiaolu/export/annotation/ExcelImport.java
0 → 100644
浏览文件 @
cdac5cb8
package
com
.
wangxiaolu
.
export
.
annotation
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* @author sunnyzyq
* @date 2021/12/17
*/
@Target
(
ElementType
.
FIELD
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
ExcelImport
{
/**
* 字段名称
*/
String
value
();
/**
* 导出映射,格式如:0-未知;1-男;2-女
*/
String
kv
()
default
""
;
/**
* 是否为必填字段(默认为非必填)
*/
boolean
required
()
default
false
;
/**
* 最大长度(默认255)
*/
int
maxLength
()
default
255
;
/**
* 导入唯一性验证(多个字段则取联合验证)
*/
boolean
unique
()
default
false
;
}
src/main/java/com/wangxiaolu/export/controller/promotion/PromotionActivityExport.java
0 → 100644
浏览文件 @
cdac5cb8
package
com
.
wangxiaolu
.
export
.
controller
.
promotion
;
import
cn.hutool.core.date.DateUtil
;
import
com.wangxiaolu.export.mapper.entity.TemporaryActivityClockDO
;
import
com.wangxiaolu.export.mapper.entity.TemporaryActivityPhotoDO
;
import
com.wangxiaolu.export.mapper.entity.TemporaryActivityReportedDO
;
import
com.wangxiaolu.export.pojo.ActivityVo
;
import
com.wangxiaolu.export.service.PromotionActivityService
;
import
com.wangxiaolu.export.util.ExcelUtils
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.util.CollectionUtils
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.servlet.http.HttpServletResponse
;
import
java.net.MalformedURLException
;
import
java.net.URL
;
import
java.util.*
;
import
java.util.stream.Collectors
;
/**
* @author : liqiulin
* @date : 2024-06-14 11
* @describe :
*/
@Slf4j
@RestController
@RequestMapping
(
"/promotion/export"
)
public
class
PromotionActivityExport
{
@Autowired
PromotionActivityService
promotionActivityService
;
@PostMapping
(
"/activity"
)
public
void
activityList
(
HttpServletResponse
response
,
@RequestBody
ActivityVo
activityVo
)
{
List
<
TemporaryActivityReportedDO
>
reportedDos
=
promotionActivityService
.
findActivityList
(
activityVo
);
List
<
Long
>
activityId
=
reportedDos
.
stream
().
map
(
TemporaryActivityReportedDO:
:
getId
).
collect
(
Collectors
.
toList
());
Map
<
Long
,
List
<
TemporaryActivityPhotoDO
>>
activityPhotos
=
promotionActivityService
.
findActivityPhotos
(
activityId
);
List
<
TemporaryActivityClockDO
>
clockPhoto
=
promotionActivityService
.
findClockPhoto
(
activityVo
);
Map
<
String
,
List
<
TemporaryActivityPhotoDO
>>
clockPhotoMap
=
new
HashMap
<>();
clockPhoto
.
stream
().
forEach
(
cp
->
{
clockPhotoMap
.
put
(
cp
.
getTemporaryId
()
+
"-"
+
cp
.
getCreateDate
(),
cp
.
getPhotoList
());
});
List
<
List
<
Object
>>
sheet
=
new
ArrayList
<>();
List
<
Object
>
headRow
=
Arrays
.
asList
(
"月份"
,
"战区"
,
"城市经理"
,
"执行城市"
,
"执行日期"
,
"场次"
,
"系统名称"
,
"门店名称"
,
"活动形式"
,
"推广活动销额(元)"
,
"真实pos证明反馈1"
,
"真实pos证明反馈2"
,
"真实pos证明反馈3"
,
"真实pos证明反馈4"
,
"上班打卡照片"
,
"午休下班打卡照片"
,
"午休上班打卡照片"
,
"下班打卡照片"
,
"推广试吃照片1"
,
"推广试吃照片2"
,
"推广试吃照片3"
,
"推广试吃照片4"
,
"推广互动照片1"
,
"推广互动照片2"
,
"推广互动照片3"
,
"推广互动照片4"
,
"推广成交照片1"
,
"推广成交照片2"
,
"推广成交照片3"
,
"推广成交照片4"
);
sheet
.
add
(
headRow
);
reportedDos
.
forEach
(
rdo
->
{
List
<
Object
>
row
=
new
ArrayList
<>();
// 月份
String
createDate
=
rdo
.
getCreateDate
();
String
clockKey
=
rdo
.
getTemporaryId
()
+
"-"
+
createDate
;
String
[]
dateArr
=
createDate
.
split
(
"-"
);
row
.
add
(
dateArr
[
1
]
+
"月"
);
// 战区
row
.
add
(
rdo
.
getOrgName
());
// 城市经理
row
.
add
(
rdo
.
getApproveName
());
// 执行城市
row
.
add
(
rdo
.
getCity
());
// 执行日期
row
.
add
(
dateArr
[
1
]
+
"月"
+
dateArr
[
2
]
+
"日"
);
// 场次
row
.
add
(
"1"
);
// 系统名称
row
.
add
(
rdo
.
getLineName
());
// 门店名称
row
.
add
(
rdo
.
getStoreName
());
// 活动形式
row
.
add
(
rdo
.
getActivityPattern
());
// 推广活动销额(元)
row
.
add
(
""
);
try
{
// 获取推广、POS图片
List
<
TemporaryActivityPhotoDO
>
temporaryActivityPhotoDOS
=
activityPhotos
.
get
(
rdo
.
getId
());
Map
<
Integer
,
List
<
TemporaryActivityPhotoDO
>>
photoTypeMap
=
new
HashMap
<>();
if
(!
CollectionUtils
.
isEmpty
(
temporaryActivityPhotoDOS
))
{
photoTypeMap
=
temporaryActivityPhotoDOS
.
stream
().
collect
(
Collectors
.
groupingBy
(
TemporaryActivityPhotoDO:
:
getType
));
}
/**
* 真实pos证明反馈
*/
List
<
TemporaryActivityPhotoDO
>
photosType7
=
Objects
.
isNull
(
photoTypeMap
.
get
(
7
))
?
new
ArrayList
<>()
:
photoTypeMap
.
get
(
7
);
int
photosType7Size
=
photosType7
.
size
();
// 真实pos证明反馈1
URL
url1
=
photosType7Size
<
1
||
Objects
.
isNull
(
photosType7
.
get
(
0
))
?
null
:
new
URL
(
photosType7
.
get
(
0
).
getPhotoUrl
());
row
.
add
(
url1
);
// 真实pos证明反馈2
URL
url2
=
photosType7Size
<
2
||
Objects
.
isNull
(
photosType7
.
get
(
1
))
?
null
:
new
URL
(
photosType7
.
get
(
1
).
getPhotoUrl
());
row
.
add
(
url2
);
// 真实pos证明反馈3
URL
url3
=
photosType7Size
<
3
||
Objects
.
isNull
(
photosType7
.
get
(
2
))
?
null
:
new
URL
(
photosType7
.
get
(
2
).
getPhotoUrl
());
row
.
add
(
url3
);
// 真实pos证明反馈4
URL
url4
=
photosType7Size
<
4
||
Objects
.
isNull
(
photosType7
.
get
(
3
))
?
null
:
new
URL
(
photosType7
.
get
(
3
).
getPhotoUrl
());
row
.
add
(
url4
);
/**
* 打卡照片
*/
List
<
TemporaryActivityPhotoDO
>
activityClock
=
clockPhotoMap
.
containsKey
(
clockKey
)
?
clockPhotoMap
.
get
(
clockKey
)
:
new
ArrayList
<>();
Map
<
Integer
,
String
>
clockMap
=
activityClock
.
stream
().
collect
(
Collectors
.
toMap
(
TemporaryActivityPhotoDO:
:
getType
,
TemporaryActivityPhotoDO:
:
getPhotoUrl
));
// 上班打卡照片
row
.
add
(
clockMap
.
containsKey
(
4
)
?
new
URL
(
clockMap
.
get
(
4
))
:
null
);
// 午休下班打卡照片
row
.
add
(
clockMap
.
containsKey
(
5
)
?
new
URL
(
clockMap
.
get
(
5
))
:
null
);
// 午休上班打卡照片
row
.
add
(
clockMap
.
containsKey
(
6
)
?
new
URL
(
clockMap
.
get
(
6
))
:
null
);
// 下班打卡照片
row
.
add
(
clockMap
.
containsKey
(
7
)
?
new
URL
(
clockMap
.
get
(
7
))
:
null
);
/**
* 推广试吃照片
*/
List
<
TemporaryActivityPhotoDO
>
photosType1
=
Objects
.
isNull
(
photoTypeMap
.
get
(
1
))
?
new
ArrayList
<>()
:
photoTypeMap
.
get
(
1
);
int
photosType1Size
=
photosType1
.
size
();
// 推广试吃照片1
URL
url1_1
=
photosType1Size
<
1
||
Objects
.
isNull
(
photosType1
.
get
(
0
))
?
null
:
new
URL
(
photosType1
.
get
(
0
).
getPhotoUrl
());
row
.
add
(
url1_1
);
// 推广试吃照片2
URL
url1_2
=
photosType1Size
<
2
||
Objects
.
isNull
(
photosType1
.
get
(
1
))
?
null
:
new
URL
(
photosType1
.
get
(
1
).
getPhotoUrl
());
row
.
add
(
url1_2
);
// 推广试吃照片3
URL
url1_3
=
photosType1Size
<
3
||
Objects
.
isNull
(
photosType1
.
get
(
2
))
?
null
:
new
URL
(
photosType1
.
get
(
2
).
getPhotoUrl
());
row
.
add
(
url1_3
);
// 推广试吃照片4
URL
url1_4
=
photosType1Size
<
4
||
Objects
.
isNull
(
photosType1
.
get
(
3
))
?
null
:
new
URL
(
photosType1
.
get
(
3
).
getPhotoUrl
());
row
.
add
(
url1_4
);
/**
* 推广互动照片
*/
List
<
TemporaryActivityPhotoDO
>
photosType2
=
Objects
.
isNull
(
photoTypeMap
.
get
(
2
))
?
new
ArrayList
<>()
:
photoTypeMap
.
get
(
2
);
int
photosType2Size
=
photosType2
.
size
();
// 推广互动照片1
URL
url2_1
=
photosType2Size
<
1
||
Objects
.
isNull
(
photosType2
.
get
(
0
))
?
null
:
new
URL
(
photosType2
.
get
(
0
).
getPhotoUrl
());
row
.
add
(
url2_1
);
// 推广互动照片2
URL
url2_2
=
photosType2Size
<
2
||
Objects
.
isNull
(
photosType2
.
get
(
1
))
?
null
:
new
URL
(
photosType2
.
get
(
1
).
getPhotoUrl
());
row
.
add
(
url2_2
);
// 推广互动照片3
URL
url2_3
=
photosType2Size
<
3
||
Objects
.
isNull
(
photosType2
.
get
(
2
))
?
null
:
new
URL
(
photosType2
.
get
(
2
).
getPhotoUrl
());
row
.
add
(
url2_3
);
// 推广互动照片4
URL
url2_4
=
photosType2Size
<
4
||
Objects
.
isNull
(
photosType2
.
get
(
3
))
?
null
:
new
URL
(
photosType2
.
get
(
3
).
getPhotoUrl
());
row
.
add
(
url2_4
);
/**
* 推广成交照片
*/
List
<
TemporaryActivityPhotoDO
>
photosType3
=
Objects
.
isNull
(
photoTypeMap
.
get
(
3
))
?
new
ArrayList
<>()
:
photoTypeMap
.
get
(
3
);
int
photosType3Size
=
photosType3
.
size
();
// 推广成交照片1
URL
url3_1
=
photosType3Size
<
1
||
Objects
.
isNull
(
photosType3
.
get
(
0
))
?
null
:
new
URL
(
photosType3
.
get
(
0
).
getPhotoUrl
());
row
.
add
(
url3_1
);
// 推广成交照片2
URL
url3_2
=
photosType3Size
<
2
||
Objects
.
isNull
(
photosType3
.
get
(
1
))
?
null
:
new
URL
(
photosType3
.
get
(
1
).
getPhotoUrl
());
row
.
add
(
url3_2
);
// 推广成交照片3
URL
url3_3
=
photosType3Size
<
3
||
Objects
.
isNull
(
photosType3
.
get
(
2
))
?
null
:
new
URL
(
photosType3
.
get
(
2
).
getPhotoUrl
());
row
.
add
(
url3_3
);
// 推广成交照片4
URL
url3_4
=
photosType3Size
<
4
||
Objects
.
isNull
(
photosType3
.
get
(
3
))
?
null
:
new
URL
(
photosType3
.
get
(
3
).
getPhotoUrl
());
row
.
add
(
url3_4
);
}
catch
(
MalformedURLException
e
)
{
log
.
error
(
"获取图片错误(MalformedURLException),抛出异常:{}"
,
e
.
getMessage
());
}
sheet
.
add
(
row
);
});
ExcelUtils
.
export
(
response
,
"活动数据导出_"
+
DateUtil
.
today
(),
sheet
);
}
}
src/main/java/com/wangxiaolu/export/mapper/TemporaryActivityClockMapper.java
0 → 100644
浏览文件 @
cdac5cb8
package
com
.
wangxiaolu
.
export
.
mapper
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
com.wangxiaolu.export.mapper.entity.TemporaryActivityClockDO
;
import
com.wangxiaolu.export.pojo.ActivityVo
;
import
org.apache.ibatis.annotations.Mapper
;
import
org.apache.ibatis.annotations.Param
;
import
org.springframework.stereotype.Repository
;
import
java.util.List
;
/**
* @author a02200059
* @description 针对表【temporary_activity_clock】的数据库操作Mapper
* @createDate 2024-04-23 17:10:46
* @Entity com.wangxiaolu.promotion.domain.activity.mapper.entity.TemporaryActivityClockDO
*/
@Mapper
@Repository
public
interface
TemporaryActivityClockMapper
extends
BaseMapper
<
TemporaryActivityClockDO
>
{
List
<
TemporaryActivityClockDO
>
findClockPhotoList
(
@Param
(
"params"
)
ActivityVo
activityVo
);
}
src/main/java/com/wangxiaolu/export/mapper/TemporaryActivityPhotoMapper.java
0 → 100644
浏览文件 @
cdac5cb8
package
com
.
wangxiaolu
.
export
.
mapper
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
com.wangxiaolu.export.mapper.entity.TemporaryActivityPhotoDO
;
import
org.apache.ibatis.annotations.Mapper
;
import
org.springframework.stereotype.Repository
;
import
java.util.List
;
/**
* @author a02200059
* @description 针对表【temporary_activity_photo】的数据库操作Mapper
* @createDate 2024-05-09 11:22:33
* @Entity com.wangxiaolu.promotion.domain.activity.mapper.entity.TemporaryActivityPhoto
*/
@Mapper
@Repository
public
interface
TemporaryActivityPhotoMapper
extends
BaseMapper
<
TemporaryActivityPhotoDO
>
{
List
<
TemporaryActivityPhotoDO
>
findActivityPhotos
(
List
<
Long
>
activityId
);
}
src/main/java/com/wangxiaolu/export/mapper/TemporaryActivityReportedMapper.java
0 → 100644
浏览文件 @
cdac5cb8
package
com
.
wangxiaolu
.
export
.
mapper
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
com.wangxiaolu.export.mapper.entity.TemporaryActivityReportedDO
;
import
com.wangxiaolu.export.pojo.ActivityVo
;
import
org.apache.ibatis.annotations.Mapper
;
import
org.apache.ibatis.annotations.Param
;
import
org.springframework.stereotype.Repository
;
import
java.util.List
;
import
java.util.Map
;
/**
* @author a02200059
* @description 针对表【temporary_activity_reported】的数据库操作Mapper
* @createDate 2024-04-18 10:38:42
* @Entity generator.domain.TemporaryActivityReported
*/
@Mapper
@Repository
public
interface
TemporaryActivityReportedMapper
extends
BaseMapper
<
TemporaryActivityReportedDO
>
{
List
<
TemporaryActivityReportedDO
>
findList
(
@Param
(
"params"
)
ActivityVo
activityVo
);
}
src/main/java/com/wangxiaolu/export/mapper/entity/TemporaryActivityClockDO.java
0 → 100644
浏览文件 @
cdac5cb8
package
com
.
wangxiaolu
.
export
.
mapper
.
entity
;
import
com.baomidou.mybatisplus.annotation.TableField
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
lombok.Data
;
import
java.io.Serializable
;
import
java.util.List
;
/**
*
* @TableName temporary_activity_clock
*/
@TableName
(
value
=
"temporary_activity_clock"
)
@Data
public
class
TemporaryActivityClockDO
implements
Serializable
{
private
Long
temporaryId
;
private
String
createDate
;
private
List
<
TemporaryActivityPhotoDO
>
photoList
;
@TableField
(
exist
=
false
)
private
static
final
long
serialVersionUID
=
1L
;
}
\ No newline at end of file
src/main/java/com/wangxiaolu/export/mapper/entity/TemporaryActivityPhotoDO.java
0 → 100644
浏览文件 @
cdac5cb8
package
com
.
wangxiaolu
.
export
.
mapper
.
entity
;
import
com.baomidou.mybatisplus.annotation.TableField
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
lombok.Data
;
import
lombok.experimental.Accessors
;
import
java.io.Serializable
;
/**
*
* @TableName temporary_activity_photo
*/
@TableName
(
value
=
"temporary_activity_photo"
)
@Data
@Accessors
(
chain
=
true
)
public
class
TemporaryActivityPhotoDO
implements
Serializable
{
/**
* 活动上报ID,关联表temporary_activity_reported表主键id
*/
private
Long
reportedId
;
/**
* 促销员上班打卡记录ID,关联temporary_activity_clock表主键ID
*/
private
Long
clockId
;
/**
* 图片所属类别:1:推广试吃;2……
*/
private
Integer
type
;
/**
* 图片http地址
*/
private
String
photoUrl
;
@TableField
(
exist
=
false
)
private
static
final
long
serialVersionUID
=
1L
;
}
\ No newline at end of file
src/main/java/com/wangxiaolu/export/mapper/entity/TemporaryActivityReportedDO.java
0 → 100644
浏览文件 @
cdac5cb8
package
com
.
wangxiaolu
.
export
.
mapper
.
entity
;
import
com.baomidou.mybatisplus.annotation.TableField
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
lombok.Data
;
import
java.io.Serializable
;
/**
*
* @TableName temporary_activity_reported
*/
@TableName
(
value
=
"temporary_activity_reported"
)
@Data
public
class
TemporaryActivityReportedDO
implements
Serializable
{
@TableId
private
Long
id
;
private
Integer
temporaryId
;
@TableField
(
exist
=
false
)
private
String
activityPattern
;
@TableField
(
exist
=
false
)
private
String
storeName
;
@TableField
(
exist
=
false
)
private
String
city
;
@TableField
(
exist
=
false
)
private
String
approveName
;
@TableField
(
exist
=
false
)
private
String
createDate
;
@TableField
(
exist
=
false
)
private
String
lineName
;
@TableField
(
exist
=
false
)
private
String
orgName
;
@TableField
(
exist
=
false
)
private
String
month
;
@TableField
(
exist
=
false
)
private
String
date
;
}
\ No newline at end of file
src/main/java/com/wangxiaolu/export/pojo/ActivityVo.java
0 → 100644
浏览文件 @
cdac5cb8
package
com
.
wangxiaolu
.
export
.
pojo
;
import
cn.hutool.core.date.DateTime
;
import
lombok.Data
;
import
java.util.Date
;
/**
* @author : liqiulin
* @date : 2024-07-03 10
* @describe :
*/
@Data
public
class
ActivityVo
{
String
createDateStart
;
String
createDateEnd
;
}
src/main/java/com/wangxiaolu/export/service/PromotionActivityService.java
0 → 100644
浏览文件 @
cdac5cb8
package
com
.
wangxiaolu
.
export
.
service
;
import
com.wangxiaolu.export.mapper.entity.TemporaryActivityClockDO
;
import
com.wangxiaolu.export.mapper.entity.TemporaryActivityPhotoDO
;
import
com.wangxiaolu.export.mapper.entity.TemporaryActivityReportedDO
;
import
com.wangxiaolu.export.pojo.ActivityVo
;
import
java.util.List
;
import
java.util.Map
;
/**
* @author : liqiulin
* @date : 2024-06-14 15
* @describe :
*/
public
interface
PromotionActivityService
{
/**
* 查询上报记录
*/
List
<
TemporaryActivityReportedDO
>
findActivityList
(
ActivityVo
activityVo
);
/**
* 查询打卡记录
*/
List
<
TemporaryActivityClockDO
>
findClockPhoto
(
ActivityVo
activityVo
);
Map
<
Long
,
List
<
TemporaryActivityPhotoDO
>>
findActivityPhotos
(
List
<
Long
>
activityId
);
}
src/main/java/com/wangxiaolu/export/service/impl/PromotionActivityServiceImpl.java
0 → 100644
浏览文件 @
cdac5cb8
package
com
.
wangxiaolu
.
export
.
service
.
impl
;
import
com.wangxiaolu.export.mapper.TemporaryActivityClockMapper
;
import
com.wangxiaolu.export.mapper.TemporaryActivityPhotoMapper
;
import
com.wangxiaolu.export.mapper.TemporaryActivityReportedMapper
;
import
com.wangxiaolu.export.mapper.entity.TemporaryActivityClockDO
;
import
com.wangxiaolu.export.mapper.entity.TemporaryActivityPhotoDO
;
import
com.wangxiaolu.export.mapper.entity.TemporaryActivityReportedDO
;
import
com.wangxiaolu.export.pojo.ActivityVo
;
import
com.wangxiaolu.export.service.PromotionActivityService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
/**
* @author : liqiulin
* @date : 2024-06-14 15
* @describe :
*/
@Service
public
class
PromotionActivityServiceImpl
implements
PromotionActivityService
{
@Autowired
TemporaryActivityReportedMapper
temporaryActivityReportedMapper
;
@Autowired
TemporaryActivityClockMapper
temporaryActivityClockMapper
;
@Autowired
TemporaryActivityPhotoMapper
temporaryActivityPhotoMapper
;
/**
* 查询上报记录
*/
@Override
public
List
<
TemporaryActivityReportedDO
>
findActivityList
(
ActivityVo
activityVo
)
{
List
<
TemporaryActivityReportedDO
>
dos
=
temporaryActivityReportedMapper
.
findList
(
activityVo
);
return
dos
;
}
/**
* 查询打卡记录
*/
@Override
public
List
<
TemporaryActivityClockDO
>
findClockPhoto
(
ActivityVo
activityVo
)
{
List
<
TemporaryActivityClockDO
>
clockPhotoList
=
temporaryActivityClockMapper
.
findClockPhotoList
(
activityVo
);
return
clockPhotoList
;
}
/**
* 根据活动记录id、打卡记录id,查询所有图片
*/
@Override
public
Map
<
Long
,
List
<
TemporaryActivityPhotoDO
>>
findActivityPhotos
(
List
<
Long
>
activityId
)
{
List
<
TemporaryActivityPhotoDO
>
activityPhotoDOS
=
temporaryActivityPhotoMapper
.
findActivityPhotos
(
activityId
);
Map
<
Long
,
List
<
TemporaryActivityPhotoDO
>>
activityPhotoMap
=
activityPhotoDOS
.
stream
().
collect
(
Collectors
.
groupingBy
(
TemporaryActivityPhotoDO:
:
getReportedId
));
return
activityPhotoMap
;
}
}
src/main/java/com/wangxiaolu/export/util/ExcelClassField.java
0 → 100644
浏览文件 @
cdac5cb8
package
com
.
wangxiaolu
.
export
.
util
;
import
java.util.LinkedHashMap
;
/**
* @author sunnyzyq
* @date 2021/12/17
*/
public
class
ExcelClassField
{
/**
* 字段名称
*/
private
String
fieldName
;
/**
* 表头名称
*/
private
String
name
;
/**
* 映射关系
*/
private
LinkedHashMap
<
String
,
String
>
kvMap
;
/**
* 示例值
*/
private
Object
example
;
/**
* 排序
*/
private
int
sort
;
/**
* 是否为注解字段:0-否,1-是
*/
private
int
hasAnnotation
;
public
String
getFieldName
()
{
return
fieldName
;
}
public
void
setFieldName
(
String
fieldName
)
{
this
.
fieldName
=
fieldName
;
}
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
LinkedHashMap
<
String
,
String
>
getKvMap
()
{
return
kvMap
;
}
public
void
setKvMap
(
LinkedHashMap
<
String
,
String
>
kvMap
)
{
this
.
kvMap
=
kvMap
;
}
public
Object
getExample
()
{
return
example
;
}
public
void
setExample
(
Object
example
)
{
this
.
example
=
example
;
}
public
int
getSort
()
{
return
sort
;
}
public
void
setSort
(
int
sort
)
{
this
.
sort
=
sort
;
}
public
int
getHasAnnotation
()
{
return
hasAnnotation
;
}
public
void
setHasAnnotation
(
int
hasAnnotation
)
{
this
.
hasAnnotation
=
hasAnnotation
;
}
}
src/main/java/com/wangxiaolu/export/util/ExcelUtils.java
0 → 100644
浏览文件 @
cdac5cb8
package
com
.
wangxiaolu
.
export
.
util
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
import
com.wangxiaolu.export.annotation.ExcelExport
;
import
com.wangxiaolu.export.annotation.ExcelImport
;
import
org.apache.poi.hssf.usermodel.HSSFDataValidation
;
import
org.apache.poi.hssf.usermodel.HSSFWorkbook
;
import
org.apache.poi.poifs.filesystem.POIFSFileSystem
;
import
org.apache.poi.ss.usermodel.*
;
import
org.apache.poi.ss.usermodel.ClientAnchor.AnchorType
;
import
org.apache.poi.ss.util.CellRangeAddress
;
import
org.apache.poi.ss.util.CellRangeAddressList
;
import
org.apache.poi.xssf.streaming.SXSSFWorkbook
;
import
org.apache.poi.xssf.usermodel.XSSFClientAnchor
;
import
org.apache.poi.xssf.usermodel.XSSFWorkbook
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.servlet.ServletOutputStream
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.*
;
import
java.lang.reflect.Field
;
import
java.math.BigDecimal
;
import
java.math.RoundingMode
;
import
java.net.URL
;
import
java.text.NumberFormat
;
import
java.text.SimpleDateFormat
;
import
java.util.*
;
import
java.util.Map.Entry
;
import
java.util.regex.Pattern
;
/**
* @author : liqiulin
* @date : 2024-06-14 11
* @describe :
*/
@SuppressWarnings
(
"unused"
)
public
class
ExcelUtils
{
private
static
final
String
XLSX
=
".xlsx"
;
private
static
final
String
XLS
=
".xls"
;
public
static
final
String
ROW_MERGE
=
"row_merge"
;
public
static
final
String
COLUMN_MERGE
=
"column_merge"
;
private
static
final
String
DATE_FORMAT
=
"yyyy-MM-dd HH:mm:ss"
;
private
static
final
String
ROW_NUM
=
"rowNum"
;
private
static
final
String
ROW_DATA
=
"rowData"
;
private
static
final
String
ROW_TIPS
=
"rowTips"
;
private
static
final
int
CELL_OTHER
=
0
;
private
static
final
int
CELL_ROW_MERGE
=
1
;
private
static
final
int
CELL_COLUMN_MERGE
=
2
;
private
static
final
int
IMG_HEIGHT
=
30
;
private
static
final
int
IMG_WIDTH
=
30
;
private
static
final
char
LEAN_LINE
=
'/'
;
private
static
final
int
BYTES_DEFAULT_LENGTH
=
10240
;
private
static
final
NumberFormat
NUMBER_FORMAT
=
NumberFormat
.
getNumberInstance
();
public
static
<
T
>
List
<
T
>
readFile
(
File
file
,
Class
<
T
>
clazz
)
throws
Exception
{
JSONArray
array
=
readFile
(
file
);
return
getBeanList
(
array
,
clazz
);
}
public
static
<
T
>
List
<
T
>
readMultipartFile
(
MultipartFile
mFile
,
Class
<
T
>
clazz
)
throws
Exception
{
JSONArray
array
=
readMultipartFile
(
mFile
);
return
getBeanList
(
array
,
clazz
);
}
public
static
JSONArray
readFile
(
File
file
)
throws
Exception
{
return
readExcel
(
null
,
file
);
}
public
static
JSONArray
readMultipartFile
(
MultipartFile
mFile
)
throws
Exception
{
return
readExcel
(
mFile
,
null
);
}
public
static
Map
<
String
,
JSONArray
>
readFileManySheet
(
File
file
)
throws
Exception
{
return
readExcelManySheet
(
null
,
file
);
}
public
static
Map
<
String
,
JSONArray
>
readFileManySheet
(
MultipartFile
file
)
throws
Exception
{
return
readExcelManySheet
(
file
,
null
);
}
private
static
<
T
>
List
<
T
>
getBeanList
(
JSONArray
array
,
Class
<
T
>
clazz
)
throws
Exception
{
List
<
T
>
list
=
new
ArrayList
<>();
Map
<
Integer
,
String
>
uniqueMap
=
new
HashMap
<>(
16
);
for
(
int
i
=
0
;
i
<
array
.
size
();
i
++)
{
list
.
add
(
getBean
(
clazz
,
array
.
getJSONObject
(
i
),
uniqueMap
));
}
return
list
;
}
/**
* 获取每个对象的数据
*/
private
static
<
T
>
T
getBean
(
Class
<
T
>
c
,
JSONObject
obj
,
Map
<
Integer
,
String
>
uniqueMap
)
throws
Exception
{
T
t
=
c
.
newInstance
();
Field
[]
fields
=
c
.
getDeclaredFields
();
List
<
String
>
errMsgList
=
new
ArrayList
<>();
boolean
hasRowTipsField
=
false
;
StringBuilder
uniqueBuilder
=
new
StringBuilder
();
int
rowNum
=
0
;
for
(
Field
field
:
fields
)
{
// 行号
if
(
field
.
getName
().
equals
(
ROW_NUM
))
{
rowNum
=
obj
.
getInteger
(
ROW_NUM
);
field
.
setAccessible
(
true
);
field
.
set
(
t
,
rowNum
);
continue
;
}
// 是否需要设置异常信息
if
(
field
.
getName
().
equals
(
ROW_TIPS
))
{
hasRowTipsField
=
true
;
continue
;
}
// 原始数据
if
(
field
.
getName
().
equals
(
ROW_DATA
))
{
field
.
setAccessible
(
true
);
field
.
set
(
t
,
obj
.
toString
());
continue
;
}
// 设置对应属性值
setFieldValue
(
t
,
field
,
obj
,
uniqueBuilder
,
errMsgList
);
}
// 数据唯一性校验
if
(
uniqueBuilder
.
length
()
>
0
)
{
if
(
uniqueMap
.
containsValue
(
uniqueBuilder
.
toString
()))
{
Set
<
Integer
>
rowNumKeys
=
uniqueMap
.
keySet
();
for
(
Integer
num
:
rowNumKeys
)
{
if
(
uniqueMap
.
get
(
num
).
equals
(
uniqueBuilder
.
toString
()))
{
errMsgList
.
add
(
String
.
format
(
"数据唯一性校验失败,(%s)与第%s行重复)"
,
uniqueBuilder
,
num
));
}
}
}
else
{
uniqueMap
.
put
(
rowNum
,
uniqueBuilder
.
toString
());
}
}
// 失败处理
if
(
errMsgList
.
isEmpty
()
&&
!
hasRowTipsField
)
{
return
t
;
}
StringBuilder
sb
=
new
StringBuilder
();
int
size
=
errMsgList
.
size
();
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
if
(
i
==
size
-
1
)
{
sb
.
append
(
errMsgList
.
get
(
i
));
}
else
{
sb
.
append
(
errMsgList
.
get
(
i
)).
append
(
";"
);
}
}
// 设置错误信息
for
(
Field
field
:
fields
)
{
if
(
field
.
getName
().
equals
(
ROW_TIPS
))
{
field
.
setAccessible
(
true
);
field
.
set
(
t
,
sb
.
toString
());
}
}
return
t
;
}
private
static
<
T
>
void
setFieldValue
(
T
t
,
Field
field
,
JSONObject
obj
,
StringBuilder
uniqueBuilder
,
List
<
String
>
errMsgList
)
{
// 获取 ExcelImport 注解属性
ExcelImport
annotation
=
field
.
getAnnotation
(
ExcelImport
.
class
);
if
(
annotation
==
null
)
{
return
;
}
String
cname
=
annotation
.
value
();
if
(
cname
.
trim
().
length
()
==
0
)
{
return
;
}
// 获取具体值
String
val
=
null
;
if
(
obj
.
containsKey
(
cname
))
{
val
=
getString
(
obj
.
getString
(
cname
));
}
if
(
val
==
null
)
{
return
;
}
field
.
setAccessible
(
true
);
// 判断是否必填
boolean
require
=
annotation
.
required
();
if
(
require
&&
val
.
isEmpty
())
{
errMsgList
.
add
(
String
.
format
(
"[%s]不能为空"
,
cname
));
return
;
}
// 数据唯一性获取
boolean
unique
=
annotation
.
unique
();
if
(
unique
)
{
if
(
uniqueBuilder
.
length
()
>
0
)
{
uniqueBuilder
.
append
(
"--"
).
append
(
val
);
}
else
{
uniqueBuilder
.
append
(
val
);
}
}
// 判断是否超过最大长度
int
maxLength
=
annotation
.
maxLength
();
if
(
maxLength
>
0
&&
val
.
length
()
>
maxLength
)
{
errMsgList
.
add
(
String
.
format
(
"[%s]长度不能超过%s个字符(当前%s个字符)"
,
cname
,
maxLength
,
val
.
length
()));
}
// 判断当前属性是否有映射关系
LinkedHashMap
<
String
,
String
>
kvMap
=
getKvMap
(
annotation
.
kv
());
if
(!
kvMap
.
isEmpty
())
{
boolean
isMatch
=
false
;
for
(
String
key
:
kvMap
.
keySet
())
{
if
(
kvMap
.
get
(
key
).
equals
(
val
))
{
val
=
key
;
isMatch
=
true
;
break
;
}
}
if
(!
isMatch
)
{
errMsgList
.
add
(
String
.
format
(
"[%s]的值不正确(当前值为%s)"
,
cname
,
val
));
return
;
}
}
// 其余情况根据类型赋值
String
fieldClassName
=
field
.
getType
().
getSimpleName
();
try
{
if
(
"String"
.
equalsIgnoreCase
(
fieldClassName
))
{
field
.
set
(
t
,
val
);
}
else
if
(
"boolean"
.
equalsIgnoreCase
(
fieldClassName
))
{
field
.
set
(
t
,
Boolean
.
valueOf
(
val
));
}
else
if
(
"int"
.
equalsIgnoreCase
(
fieldClassName
)
||
"Integer"
.
equals
(
fieldClassName
))
{
try
{
field
.
set
(
t
,
Integer
.
valueOf
(
val
));
}
catch
(
NumberFormatException
e
)
{
errMsgList
.
add
(
String
.
format
(
"[%s]的值格式不正确(当前值为%s)"
,
cname
,
val
));
}
}
else
if
(
"double"
.
equalsIgnoreCase
(
fieldClassName
))
{
field
.
set
(
t
,
Double
.
valueOf
(
val
));
}
else
if
(
"long"
.
equalsIgnoreCase
(
fieldClassName
))
{
field
.
set
(
t
,
Long
.
valueOf
(
val
));
}
else
if
(
"BigDecimal"
.
equalsIgnoreCase
(
fieldClassName
))
{
field
.
set
(
t
,
new
BigDecimal
(
val
));
}
else
if
(
"Date"
.
equalsIgnoreCase
(
fieldClassName
))
{
try
{
field
.
set
(
t
,
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
).
parse
(
val
));
}
catch
(
Exception
e
)
{
field
.
set
(
t
,
new
SimpleDateFormat
(
"yyyy-MM-dd"
).
parse
(
val
));
}
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
private
static
Map
<
String
,
JSONArray
>
readExcelManySheet
(
MultipartFile
mFile
,
File
file
)
throws
IOException
{
Workbook
book
=
getWorkbook
(
mFile
,
file
);
if
(
book
==
null
)
{
return
Collections
.
emptyMap
();
}
Map
<
String
,
JSONArray
>
map
=
new
LinkedHashMap
<>();
for
(
int
i
=
0
;
i
<
book
.
getNumberOfSheets
();
i
++)
{
Sheet
sheet
=
book
.
getSheetAt
(
i
);
JSONArray
arr
=
readSheet
(
sheet
);
map
.
put
(
sheet
.
getSheetName
(),
arr
);
}
book
.
close
();
return
map
;
}
private
static
JSONArray
readExcel
(
MultipartFile
mFile
,
File
file
)
throws
IOException
{
Workbook
book
=
getWorkbook
(
mFile
,
file
);
if
(
book
==
null
)
{
return
new
JSONArray
();
}
JSONArray
array
=
readSheet
(
book
.
getSheetAt
(
0
));
book
.
close
();
return
array
;
}
private
static
Workbook
getWorkbook
(
MultipartFile
mFile
,
File
file
)
throws
IOException
{
boolean
fileNotExist
=
(
file
==
null
||
!
file
.
exists
());
if
(
mFile
==
null
&&
fileNotExist
)
{
return
null
;
}
// 解析表格数据
InputStream
in
;
String
fileName
;
if
(
mFile
!=
null
)
{
// 上传文件解析
in
=
mFile
.
getInputStream
();
fileName
=
getString
(
mFile
.
getOriginalFilename
()).
toLowerCase
();
}
else
{
// 本地文件解析
in
=
new
FileInputStream
(
file
);
fileName
=
file
.
getName
().
toLowerCase
();
}
Workbook
book
;
if
(
fileName
.
endsWith
(
XLSX
))
{
book
=
new
XSSFWorkbook
(
in
);
}
else
if
(
fileName
.
endsWith
(
XLS
))
{
POIFSFileSystem
poifsFileSystem
=
new
POIFSFileSystem
(
in
);
book
=
new
HSSFWorkbook
(
poifsFileSystem
);
}
else
{
return
null
;
}
in
.
close
();
return
book
;
}
private
static
JSONArray
readSheet
(
Sheet
sheet
)
{
// 首行下标
int
rowStart
=
sheet
.
getFirstRowNum
();
// 尾行下标
int
rowEnd
=
sheet
.
getLastRowNum
();
// 获取表头行
Row
headRow
=
sheet
.
getRow
(
rowStart
);
if
(
headRow
==
null
)
{
return
new
JSONArray
();
}
int
cellStart
=
headRow
.
getFirstCellNum
();
int
cellEnd
=
headRow
.
getLastCellNum
();
Map
<
Integer
,
String
>
keyMap
=
new
HashMap
<>();
for
(
int
j
=
cellStart
;
j
<
cellEnd
;
j
++)
{
// 获取表头数据
String
val
=
getCellValue
(
headRow
.
getCell
(
j
));
if
(
val
!=
null
&&
val
.
trim
().
length
()
!=
0
)
{
keyMap
.
put
(
j
,
val
);
}
}
// 如果表头没有数据则不进行解析
if
(
keyMap
.
isEmpty
())
{
return
(
JSONArray
)
Collections
.
emptyList
();
}
// 获取每行JSON对象的值
JSONArray
array
=
new
JSONArray
();
// 如果首行与尾行相同,表明只有一行,返回表头数据
if
(
rowStart
==
rowEnd
)
{
JSONObject
obj
=
new
JSONObject
();
// 添加行号
obj
.
put
(
ROW_NUM
,
1
);
for
(
int
i
:
keyMap
.
keySet
())
{
obj
.
put
(
keyMap
.
get
(
i
),
""
);
}
array
.
add
(
obj
);
return
array
;
}
for
(
int
i
=
rowStart
+
1
;
i
<=
rowEnd
;
i
++)
{
Row
eachRow
=
sheet
.
getRow
(
i
);
JSONObject
obj
=
new
JSONObject
();
// 添加行号
obj
.
put
(
ROW_NUM
,
i
+
1
);
StringBuilder
sb
=
new
StringBuilder
();
for
(
int
k
=
cellStart
;
k
<
cellEnd
;
k
++)
{
if
(
eachRow
!=
null
)
{
String
val
=
getCellValue
(
eachRow
.
getCell
(
k
));
// 所有数据添加到里面,用于判断该行是否为空
sb
.
append
(
val
);
obj
.
put
(
keyMap
.
get
(
k
),
val
);
}
}
if
(
sb
.
length
()
>
0
)
{
array
.
add
(
obj
);
}
}
return
array
;
}
private
static
String
getCellValue
(
Cell
cell
)
{
// 空白或空
if
(
cell
==
null
||
cell
.
getCellTypeEnum
()
==
CellType
.
BLANK
)
{
return
""
;
}
// String类型
if
(
cell
.
getCellTypeEnum
()
==
CellType
.
STRING
)
{
String
val
=
cell
.
getStringCellValue
();
if
(
val
==
null
||
val
.
trim
().
length
()
==
0
)
{
return
""
;
}
return
val
.
trim
();
}
// 数字类型
if
(
cell
.
getCellTypeEnum
()
==
CellType
.
NUMERIC
)
{
String
s
=
cell
.
getNumericCellValue
()
+
""
;
// 去掉尾巴上的小数点0
if
(
Pattern
.
matches
(
".*\\.0*"
,
s
))
{
return
s
.
split
(
"\\."
)[
0
];
}
else
{
return
s
;
}
}
// 布尔值类型
if
(
cell
.
getCellTypeEnum
()
==
CellType
.
BOOLEAN
)
{
return
cell
.
getBooleanCellValue
()
+
""
;
}
// 错误类型
return
cell
.
getCellFormula
();
}
public
static
<
T
>
void
exportTemplate
(
HttpServletResponse
response
,
String
fileName
,
Class
<
T
>
clazz
)
{
exportTemplate
(
response
,
fileName
,
fileName
,
clazz
,
false
);
}
public
static
<
T
>
void
exportTemplate
(
HttpServletResponse
response
,
String
fileName
,
String
sheetName
,
Class
<
T
>
clazz
)
{
exportTemplate
(
response
,
fileName
,
sheetName
,
clazz
,
false
);
}
public
static
<
T
>
void
exportTemplate
(
HttpServletResponse
response
,
String
fileName
,
Class
<
T
>
clazz
,
boolean
isContainExample
)
{
exportTemplate
(
response
,
fileName
,
fileName
,
clazz
,
isContainExample
);
}
public
static
<
T
>
void
exportTemplate
(
HttpServletResponse
response
,
String
fileName
,
String
sheetName
,
Class
<
T
>
clazz
,
boolean
isContainExample
)
{
// 获取表头字段
List
<
ExcelClassField
>
headFieldList
=
getExcelClassFieldList
(
clazz
);
// 获取表头数据和示例数据
List
<
List
<
Object
>>
sheetDataList
=
new
ArrayList
<>();
List
<
Object
>
headList
=
new
ArrayList
<>();
List
<
Object
>
exampleList
=
new
ArrayList
<>();
Map
<
Integer
,
List
<
String
>>
selectMap
=
new
LinkedHashMap
<>();
for
(
int
i
=
0
;
i
<
headFieldList
.
size
();
i
++)
{
ExcelClassField
each
=
headFieldList
.
get
(
i
);
headList
.
add
(
each
.
getName
());
exampleList
.
add
(
each
.
getExample
());
LinkedHashMap
<
String
,
String
>
kvMap
=
each
.
getKvMap
();
if
(
kvMap
!=
null
&&
kvMap
.
size
()
>
0
)
{
selectMap
.
put
(
i
,
new
ArrayList
<>(
kvMap
.
values
()));
}
}
sheetDataList
.
add
(
headList
);
if
(
isContainExample
)
{
sheetDataList
.
add
(
exampleList
);
}
// 导出数据
export
(
response
,
fileName
,
sheetName
,
sheetDataList
,
selectMap
);
}
private
static
<
T
>
List
<
ExcelClassField
>
getExcelClassFieldList
(
Class
<
T
>
clazz
)
{
// 解析所有字段
Field
[]
fields
=
clazz
.
getDeclaredFields
();
boolean
hasExportAnnotation
=
false
;
Map
<
Integer
,
List
<
ExcelClassField
>>
map
=
new
LinkedHashMap
<>();
List
<
Integer
>
sortList
=
new
ArrayList
<>();
for
(
Field
field
:
fields
)
{
ExcelClassField
cf
=
getExcelClassField
(
field
);
if
(
cf
.
getHasAnnotation
()
==
1
)
{
hasExportAnnotation
=
true
;
}
int
sort
=
cf
.
getSort
();
if
(
map
.
containsKey
(
sort
))
{
map
.
get
(
sort
).
add
(
cf
);
}
else
{
List
<
ExcelClassField
>
list
=
new
ArrayList
<>();
list
.
add
(
cf
);
sortList
.
add
(
sort
);
map
.
put
(
sort
,
list
);
}
}
Collections
.
sort
(
sortList
);
// 获取表头
List
<
ExcelClassField
>
headFieldList
=
new
ArrayList
<>();
if
(
hasExportAnnotation
)
{
for
(
Integer
sort
:
sortList
)
{
for
(
ExcelClassField
cf
:
map
.
get
(
sort
))
{
if
(
cf
.
getHasAnnotation
()
==
1
)
{
headFieldList
.
add
(
cf
);
}
}
}
}
else
{
headFieldList
.
addAll
(
map
.
get
(
0
));
}
return
headFieldList
;
}
private
static
ExcelClassField
getExcelClassField
(
Field
field
)
{
ExcelClassField
cf
=
new
ExcelClassField
();
String
fieldName
=
field
.
getName
();
cf
.
setFieldName
(
fieldName
);
ExcelExport
annotation
=
field
.
getAnnotation
(
ExcelExport
.
class
);
// 无 ExcelExport 注解情况
if
(
annotation
==
null
)
{
cf
.
setHasAnnotation
(
0
);
cf
.
setName
(
fieldName
);
cf
.
setSort
(
0
);
return
cf
;
}
// 有 ExcelExport 注解情况
cf
.
setHasAnnotation
(
1
);
cf
.
setName
(
annotation
.
value
());
String
example
=
getString
(
annotation
.
example
());
if
(!
example
.
isEmpty
())
{
if
(
isNumeric
(
example
)
&&
example
.
length
()
<
8
)
{
cf
.
setExample
(
Double
.
valueOf
(
example
));
}
else
{
cf
.
setExample
(
example
);
}
}
else
{
cf
.
setExample
(
""
);
}
cf
.
setSort
(
annotation
.
sort
());
// 解析映射
String
kv
=
getString
(
annotation
.
kv
());
cf
.
setKvMap
(
getKvMap
(
kv
));
return
cf
;
}
private
static
LinkedHashMap
<
String
,
String
>
getKvMap
(
String
kv
)
{
LinkedHashMap
<
String
,
String
>
kvMap
=
new
LinkedHashMap
<>();
if
(
kv
.
isEmpty
())
{
return
kvMap
;
}
String
[]
kvs
=
kv
.
split
(
";"
);
if
(
kvs
.
length
==
0
)
{
return
kvMap
;
}
for
(
String
each
:
kvs
)
{
String
[]
eachKv
=
getString
(
each
).
split
(
"-"
);
if
(
eachKv
.
length
!=
2
)
{
continue
;
}
String
k
=
eachKv
[
0
];
String
v
=
eachKv
[
1
];
if
(
k
.
isEmpty
()
||
v
.
isEmpty
())
{
continue
;
}
kvMap
.
put
(
k
,
v
);
}
return
kvMap
;
}
/**
* 导出表格到本地
*
* @param file 本地文件对象
* @param sheetData 导出数据
*/
public
static
void
exportFile
(
File
file
,
List
<
List
<
Object
>>
sheetData
)
{
if
(
file
==
null
)
{
System
.
out
.
println
(
"文件创建失败"
);
return
;
}
if
(
sheetData
==
null
)
{
sheetData
=
new
ArrayList
<>();
}
Map
<
String
,
List
<
List
<
Object
>>>
map
=
new
HashMap
<>();
map
.
put
(
file
.
getName
(),
sheetData
);
export
(
null
,
file
,
file
.
getName
(),
map
,
null
);
}
/**
* 导出表格到本地
*
* @param <T> 导出数据类似,和K类型保持一致
* @param filePath 文件父路径(如:D:/doc/excel/)
* @param fileName 文件名称(不带尾缀,如:学生表)
* @param list 导出数据
* @throws IOException IO异常
*/
public
static
<
T
>
File
exportFile
(
String
filePath
,
String
fileName
,
List
<
T
>
list
)
throws
IOException
{
File
file
=
getFile
(
filePath
,
fileName
);
List
<
List
<
Object
>>
sheetData
=
getSheetData
(
list
);
exportFile
(
file
,
sheetData
);
return
file
;
}
/**
* 获取文件
*
* @param filePath filePath 文件父路径(如:D:/doc/excel/)
* @param fileName 文件名称(不带尾缀,如:用户表)
* @return 本地File文件对象
*/
private
static
File
getFile
(
String
filePath
,
String
fileName
)
throws
IOException
{
String
dirPath
=
getString
(
filePath
);
String
fileFullPath
;
if
(
dirPath
.
isEmpty
())
{
fileFullPath
=
fileName
;
}
else
{
// 判定文件夹是否存在,如果不存在,则级联创建
File
dirFile
=
new
File
(
dirPath
);
if
(!
dirFile
.
exists
())
{
boolean
mkdirs
=
dirFile
.
mkdirs
();
if
(!
mkdirs
)
{
return
null
;
}
}
// 获取文件夹全名
if
(
dirPath
.
endsWith
(
String
.
valueOf
(
LEAN_LINE
)))
{
fileFullPath
=
dirPath
+
fileName
+
XLSX
;
}
else
{
fileFullPath
=
dirPath
+
LEAN_LINE
+
fileName
+
XLSX
;
}
}
System
.
out
.
println
(
fileFullPath
);
File
file
=
new
File
(
fileFullPath
);
if
(!
file
.
exists
())
{
boolean
result
=
file
.
createNewFile
();
if
(!
result
)
{
return
null
;
}
}
return
file
;
}
private
static
<
T
>
List
<
List
<
Object
>>
getSheetData
(
List
<
T
>
list
)
{
// 获取表头字段
List
<
ExcelClassField
>
excelClassFieldList
=
getExcelClassFieldList
(
list
.
get
(
0
).
getClass
());
List
<
String
>
headFieldList
=
new
ArrayList
<>();
List
<
Object
>
headList
=
new
ArrayList
<>();
Map
<
String
,
ExcelClassField
>
headFieldMap
=
new
HashMap
<>();
for
(
ExcelClassField
each
:
excelClassFieldList
)
{
String
fieldName
=
each
.
getFieldName
();
headFieldList
.
add
(
fieldName
);
headFieldMap
.
put
(
fieldName
,
each
);
headList
.
add
(
each
.
getName
());
}
// 添加表头名称
List
<
List
<
Object
>>
sheetDataList
=
new
ArrayList
<>();
sheetDataList
.
add
(
headList
);
// 获取表数据
for
(
T
t
:
list
)
{
Map
<
String
,
Object
>
fieldDataMap
=
getFieldDataMap
(
t
);
Set
<
String
>
fieldDataKeys
=
fieldDataMap
.
keySet
();
List
<
Object
>
rowList
=
new
ArrayList
<>();
for
(
String
headField
:
headFieldList
)
{
if
(!
fieldDataKeys
.
contains
(
headField
))
{
continue
;
}
Object
data
=
fieldDataMap
.
get
(
headField
);
if
(
data
==
null
)
{
rowList
.
add
(
""
);
continue
;
}
ExcelClassField
cf
=
headFieldMap
.
get
(
headField
);
// 判断是否有映射关系
LinkedHashMap
<
String
,
String
>
kvMap
=
cf
.
getKvMap
();
if
(
kvMap
==
null
||
kvMap
.
isEmpty
())
{
rowList
.
add
(
data
);
continue
;
}
String
val
=
kvMap
.
get
(
data
.
toString
());
if
(
isNumeric
(
val
))
{
rowList
.
add
(
Double
.
valueOf
(
val
));
}
else
{
rowList
.
add
(
val
);
}
}
sheetDataList
.
add
(
rowList
);
}
return
sheetDataList
;
}
private
static
<
T
>
Map
<
String
,
Object
>
getFieldDataMap
(
T
t
)
{
Map
<
String
,
Object
>
map
=
new
HashMap
<>();
Field
[]
fields
=
t
.
getClass
().
getDeclaredFields
();
try
{
for
(
Field
field
:
fields
)
{
String
fieldName
=
field
.
getName
();
field
.
setAccessible
(
true
);
Object
object
=
field
.
get
(
t
);
map
.
put
(
fieldName
,
object
);
}
}
catch
(
IllegalArgumentException
|
IllegalAccessException
e
)
{
e
.
printStackTrace
();
}
return
map
;
}
public
static
void
exportEmpty
(
HttpServletResponse
response
,
String
fileName
)
{
List
<
List
<
Object
>>
sheetDataList
=
new
ArrayList
<>();
List
<
Object
>
headList
=
new
ArrayList
<>();
headList
.
add
(
"导出无数据"
);
sheetDataList
.
add
(
headList
);
export
(
response
,
fileName
,
sheetDataList
);
}
public
static
void
export
(
HttpServletResponse
response
,
String
fileName
,
List
<
List
<
Object
>>
sheetDataList
)
{
export
(
response
,
fileName
,
fileName
,
sheetDataList
,
null
);
}
public
static
void
exportManySheet
(
HttpServletResponse
response
,
String
fileName
,
Map
<
String
,
List
<
List
<
Object
>>>
sheetMap
)
{
export
(
response
,
null
,
fileName
,
sheetMap
,
null
);
}
public
static
void
export
(
HttpServletResponse
response
,
String
fileName
,
String
sheetName
,
List
<
List
<
Object
>>
sheetDataList
)
{
export
(
response
,
fileName
,
sheetName
,
sheetDataList
,
null
);
}
public
static
void
export
(
HttpServletResponse
response
,
String
fileName
,
String
sheetName
,
List
<
List
<
Object
>>
sheetDataList
,
Map
<
Integer
,
List
<
String
>>
selectMap
)
{
Map
<
String
,
List
<
List
<
Object
>>>
map
=
new
HashMap
<>();
map
.
put
(
sheetName
,
sheetDataList
);
export
(
response
,
null
,
fileName
,
map
,
selectMap
);
}
public
static
<
T
,
K
>
void
export
(
HttpServletResponse
response
,
String
fileName
,
List
<
T
>
list
,
Class
<
K
>
template
)
{
// list 是否为空
boolean
lisIsEmpty
=
list
==
null
||
list
.
isEmpty
();
// 如果模板数据为空,且导入的数据为空,则导出空文件
if
(
template
==
null
&&
lisIsEmpty
)
{
exportEmpty
(
response
,
fileName
);
return
;
}
// 如果 list 数据,则导出模板数据
if
(
lisIsEmpty
)
{
exportTemplate
(
response
,
fileName
,
template
);
return
;
}
// 导出数据
List
<
List
<
Object
>>
sheetDataList
=
getSheetData
(
list
);
export
(
response
,
fileName
,
sheetDataList
);
}
public
static
void
export
(
HttpServletResponse
response
,
String
fileName
,
List
<
List
<
Object
>>
sheetDataList
,
Map
<
Integer
,
List
<
String
>>
selectMap
)
{
export
(
response
,
fileName
,
fileName
,
sheetDataList
,
selectMap
);
}
private
static
void
export
(
HttpServletResponse
response
,
File
file
,
String
fileName
,
Map
<
String
,
List
<
List
<
Object
>>>
sheetMap
,
Map
<
Integer
,
List
<
String
>>
selectMap
)
{
// 整个 Excel 表格 book 对象
SXSSFWorkbook
book
=
new
SXSSFWorkbook
();
// 每个 Sheet 页
Set
<
Entry
<
String
,
List
<
List
<
Object
>>>>
entries
=
sheetMap
.
entrySet
();
for
(
Entry
<
String
,
List
<
List
<
Object
>>>
entry
:
entries
)
{
List
<
List
<
Object
>>
sheetDataList
=
entry
.
getValue
();
Sheet
sheet
=
book
.
createSheet
(
entry
.
getKey
());
Drawing
<?>
patriarch
=
sheet
.
createDrawingPatriarch
();
// 设置表头背景色(灰色)
CellStyle
headStyle
=
book
.
createCellStyle
();
headStyle
.
setFillForegroundColor
(
IndexedColors
.
GREY_80_PERCENT
.
index
);
headStyle
.
setFillPattern
(
FillPatternType
.
SOLID_FOREGROUND
);
headStyle
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
headStyle
.
setFillForegroundColor
(
IndexedColors
.
GREY_25_PERCENT
.
index
);
// 设置表身背景色(默认色)
CellStyle
rowStyle
=
book
.
createCellStyle
();
rowStyle
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
rowStyle
.
setVerticalAlignment
(
VerticalAlignment
.
CENTER
);
// 设置表格列宽度(默认为15个字节)
sheet
.
setDefaultColumnWidth
(
15
);
// 创建合并算法数组
int
rowLength
=
sheetDataList
.
size
();
int
columnLength
=
sheetDataList
.
get
(
0
).
size
();
int
[][]
mergeArray
=
new
int
[
rowLength
][
columnLength
];
for
(
int
i
=
0
;
i
<
sheetDataList
.
size
();
i
++)
{
// 每个 Sheet 页中的行数据
Row
row
=
sheet
.
createRow
(
i
);
List
<
Object
>
rowList
=
sheetDataList
.
get
(
i
);
for
(
int
j
=
0
;
j
<
rowList
.
size
();
j
++)
{
// 每个行数据中的单元格数据
Object
o
=
rowList
.
get
(
j
);
int
v
=
0
;
if
(
o
instanceof
URL
)
{
// 如果要导出图片的话, 链接需要传递 URL 对象
setCellPicture
(
book
,
row
,
patriarch
,
i
,
j
,
(
URL
)
o
);
}
else
{
Cell
cell
=
row
.
createCell
(
j
);
if
(
i
==
0
)
{
// 第一行为表头行,采用灰色底背景
v
=
setCellValue
(
cell
,
o
,
headStyle
);
}
else
{
// 其他行为数据行,默认白底色
v
=
setCellValue
(
cell
,
o
,
rowStyle
);
}
}
mergeArray
[
i
][
j
]
=
v
;
}
}
// 合并单元格
mergeCells
(
sheet
,
mergeArray
);
// 设置下拉列表
setSelect
(
sheet
,
selectMap
);
}
// 写数据
if
(
response
!=
null
)
{
// 前端导出
try
{
write
(
response
,
book
,
fileName
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
else
{
// 本地导出
FileOutputStream
fos
;
try
{
fos
=
new
FileOutputStream
(
file
);
ByteArrayOutputStream
ops
=
new
ByteArrayOutputStream
();
book
.
write
(
ops
);
fos
.
write
(
ops
.
toByteArray
());
fos
.
close
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
/**
* 合并当前Sheet页的单元格
*
* @param sheet 当前 sheet 页
* @param mergeArray 合并单元格算法
*/
private
static
void
mergeCells
(
Sheet
sheet
,
int
[][]
mergeArray
)
{
// 横向合并
for
(
int
x
=
0
;
x
<
mergeArray
.
length
;
x
++)
{
int
[]
arr
=
mergeArray
[
x
];
boolean
merge
=
false
;
int
y1
=
0
;
int
y2
=
0
;
for
(
int
y
=
0
;
y
<
arr
.
length
;
y
++)
{
int
value
=
arr
[
y
];
if
(
value
==
CELL_COLUMN_MERGE
)
{
if
(!
merge
)
{
y1
=
y
;
}
y2
=
y
;
merge
=
true
;
}
else
{
merge
=
false
;
if
(
y1
>
0
)
{
sheet
.
addMergedRegion
(
new
CellRangeAddress
(
x
,
x
,
(
y1
-
1
),
y2
));
}
y1
=
0
;
y2
=
0
;
}
}
if
(
y1
>
0
)
{
sheet
.
addMergedRegion
(
new
CellRangeAddress
(
x
,
x
,
(
y1
-
1
),
y2
));
}
}
// 纵向合并
int
xLen
=
mergeArray
.
length
;
int
yLen
=
mergeArray
[
0
].
length
;
for
(
int
y
=
0
;
y
<
yLen
;
y
++)
{
boolean
merge
=
false
;
int
x1
=
0
;
int
x2
=
0
;
for
(
int
x
=
0
;
x
<
xLen
;
x
++)
{
int
value
=
mergeArray
[
x
][
y
];
if
(
value
==
CELL_ROW_MERGE
)
{
if
(!
merge
)
{
x1
=
x
;
}
x2
=
x
;
merge
=
true
;
}
else
{
merge
=
false
;
if
(
x1
>
0
)
{
sheet
.
addMergedRegion
(
new
CellRangeAddress
((
x1
-
1
),
x2
,
y
,
y
));
}
x1
=
0
;
x2
=
0
;
}
}
if
(
x1
>
0
)
{
sheet
.
addMergedRegion
(
new
CellRangeAddress
((
x1
-
1
),
x2
,
y
,
y
));
}
}
}
private
static
void
write
(
HttpServletResponse
response
,
SXSSFWorkbook
book
,
String
fileName
)
throws
IOException
{
response
.
setContentType
(
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
);
response
.
setCharacterEncoding
(
"utf-8"
);
String
name
=
new
String
(
fileName
.
getBytes
(
"GBK"
),
"ISO8859_1"
)
+
XLSX
;
response
.
addHeader
(
"Content-Disposition"
,
"attachment;filename="
+
name
);
ServletOutputStream
out
=
response
.
getOutputStream
();
book
.
write
(
out
);
out
.
flush
();
out
.
close
();
}
private
static
int
setCellValue
(
Cell
cell
,
Object
o
,
CellStyle
style
)
{
// 设置样式
cell
.
setCellStyle
(
style
);
// 数据为空时
if
(
o
==
null
)
{
cell
.
setCellType
(
CellType
.
STRING
);
cell
.
setCellValue
(
""
);
return
CELL_OTHER
;
}
// 是否为字符串
if
(
o
instanceof
String
)
{
String
s
=
o
.
toString
();
// 当数字类型长度超过8位时,改为字符串类型显示(Excel数字超过一定长度会显示为科学计数法)
if
(
isNumeric
(
s
)
&&
s
.
length
()
<
8
)
{
cell
.
setCellType
(
CellType
.
NUMERIC
);
cell
.
setCellValue
(
Double
.
parseDouble
(
s
));
return
CELL_OTHER
;
}
else
{
cell
.
setCellType
(
CellType
.
STRING
);
cell
.
setCellValue
(
s
);
}
if
(
s
.
equals
(
ROW_MERGE
))
{
return
CELL_ROW_MERGE
;
}
else
if
(
s
.
equals
(
COLUMN_MERGE
))
{
return
CELL_COLUMN_MERGE
;
}
else
{
return
CELL_OTHER
;
}
}
// 是否为字符串
if
(
o
instanceof
Integer
||
o
instanceof
Long
||
o
instanceof
Double
||
o
instanceof
Float
)
{
cell
.
setCellType
(
CellType
.
NUMERIC
);
cell
.
setCellValue
(
Double
.
parseDouble
(
o
.
toString
()));
return
CELL_OTHER
;
}
// 是否为Boolean
if
(
o
instanceof
Boolean
)
{
cell
.
setCellType
(
CellType
.
BOOLEAN
);
cell
.
setCellValue
((
Boolean
)
o
);
return
CELL_OTHER
;
}
// 如果是BigDecimal,则默认3位小数
if
(
o
instanceof
BigDecimal
)
{
cell
.
setCellType
(
CellType
.
NUMERIC
);
cell
.
setCellValue
(((
BigDecimal
)
o
).
setScale
(
3
,
RoundingMode
.
HALF_UP
).
doubleValue
());
return
CELL_OTHER
;
}
// 如果是Date数据,则显示格式化数据
if
(
o
instanceof
Date
)
{
cell
.
setCellType
(
CellType
.
STRING
);
cell
.
setCellValue
(
formatDate
((
Date
)
o
));
return
CELL_OTHER
;
}
// 如果是其他,则默认字符串类型
cell
.
setCellType
(
CellType
.
STRING
);
cell
.
setCellValue
(
o
.
toString
());
return
CELL_OTHER
;
}
private
static
void
setCellPicture
(
SXSSFWorkbook
wb
,
Row
sr
,
Drawing
<?>
patriarch
,
int
x
,
int
y
,
URL
url
)
{
// 设置图片宽高
sr
.
setHeight
((
short
)
(
IMG_WIDTH
*
IMG_HEIGHT
));
// (jdk1.7版本try中定义流可自动关闭)
try
(
InputStream
is
=
url
.
openStream
();
ByteArrayOutputStream
outputStream
=
new
ByteArrayOutputStream
())
{
byte
[]
buff
=
new
byte
[
BYTES_DEFAULT_LENGTH
];
int
rc
;
while
((
rc
=
is
.
read
(
buff
,
0
,
BYTES_DEFAULT_LENGTH
))
>
0
)
{
outputStream
.
write
(
buff
,
0
,
rc
);
}
// 设置图片位置
XSSFClientAnchor
anchor
=
new
XSSFClientAnchor
(
0
,
0
,
0
,
0
,
y
,
x
,
y
+
1
,
x
+
1
);
// 设置这个,图片会自动填满单元格的长宽
anchor
.
setAnchorType
(
AnchorType
.
MOVE_AND_RESIZE
);
patriarch
.
createPicture
(
anchor
,
wb
.
addPicture
(
outputStream
.
toByteArray
(),
HSSFWorkbook
.
PICTURE_TYPE_JPEG
));
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
private
static
String
formatDate
(
Date
date
)
{
if
(
date
==
null
)
{
return
""
;
}
SimpleDateFormat
format
=
new
SimpleDateFormat
(
DATE_FORMAT
);
return
format
.
format
(
date
);
}
private
static
void
setSelect
(
Sheet
sheet
,
Map
<
Integer
,
List
<
String
>>
selectMap
)
{
if
(
selectMap
==
null
||
selectMap
.
isEmpty
())
{
return
;
}
Set
<
Entry
<
Integer
,
List
<
String
>>>
entrySet
=
selectMap
.
entrySet
();
for
(
Entry
<
Integer
,
List
<
String
>>
entry
:
entrySet
)
{
int
y
=
entry
.
getKey
();
List
<
String
>
list
=
entry
.
getValue
();
if
(
list
==
null
||
list
.
isEmpty
())
{
continue
;
}
String
[]
arr
=
new
String
[
list
.
size
()];
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
arr
[
i
]
=
list
.
get
(
i
);
}
DataValidationHelper
helper
=
sheet
.
getDataValidationHelper
();
CellRangeAddressList
addressList
=
new
CellRangeAddressList
(
1
,
65000
,
y
,
y
);
DataValidationConstraint
dvc
=
helper
.
createExplicitListConstraint
(
arr
);
DataValidation
dv
=
helper
.
createValidation
(
dvc
,
addressList
);
if
(
dv
instanceof
HSSFDataValidation
)
{
dv
.
setSuppressDropDownArrow
(
false
);
}
else
{
dv
.
setSuppressDropDownArrow
(
true
);
dv
.
setShowErrorBox
(
true
);
}
sheet
.
addValidationData
(
dv
);
}
}
private
static
boolean
isNumeric
(
String
str
)
{
if
(
Objects
.
isNull
(
str
)
||
""
.
equals
(
str
)){
return
false
;
}
if
(
"0.0"
.
equals
(
str
))
{
return
true
;
}
for
(
int
i
=
str
.
length
();
--
i
>=
0
;
)
{
if
(!
Character
.
isDigit
(
str
.
charAt
(
i
)))
{
return
false
;
}
}
return
true
;
}
private
static
String
getString
(
String
s
)
{
if
(
s
==
null
)
{
return
""
;
}
if
(
s
.
isEmpty
())
{
return
s
;
}
return
s
.
trim
();
}
}
src/main/resources/application-dev.yml
0 → 100644
浏览文件 @
cdac5cb8
spring
:
datasource
:
driver-class-name
:
com.mysql.jdbc.Driver
url
:
jdbc:mysql://bj-cdb-j8ppdy86.sql.tencentcdb.com:63569/promotion_dev?autoReconnect=true
username
:
LnNDBM
password
:
fd0%bhD4@oO(%
# redis:
# port: 21101
# host: bj-crs-oyzhz3c6.sql.tencentcdb.com
# database: 0
# password: u)R3jrHk(qwt~mv$Tg=U
cloud
:
nacos
:
discovery
:
server-addr
:
42.193.103.153:8848
namespace
:
dd681f3c-0d21-42e5-a96e-14863a7cdcdb
group
:
promotion
src/main/resources/application-live.yml
0 → 100644
浏览文件 @
cdac5cb8
spring
:
datasource
:
driver-class-name
:
com.mysql.jdbc.Driver
url
:
jdbc:mysql://192.168.0.18:3306/promotion?autoReconnect=true
username
:
NvqGbJXH
password
:
D9Y@FR,84B*$MD^A36&m
# redis:
# port: 21101
# host: bj-crs-oyzhz3c6.sql.tencentcdb.com
# database: 0
# password: u)R3jrHk(qwt~mv$Tg=U
cloud
:
nacos
:
discovery
:
server-addr
:
192.168.0.2:8848
namespace
:
5a4d4bfc-5297-4c6f-b475-0a6ae838d8d9
group
:
promotion
src/main/resources/application.properties
deleted
100644 → 0
浏览文件 @
cbe92da0
spring.application.name
=
wangxiaolu-export
src/main/resources/application.yml
0 → 100644
浏览文件 @
cdac5cb8
server
:
port
:
8012
spring
:
application
:
name
:
wangxiaolu-export
profiles
:
active
:
dev
\ No newline at end of file
src/main/resources/mapper/TemporaryActivityClockMapper.xml
0 → 100644
浏览文件 @
cdac5cb8
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.wangxiaolu.export.mapper.TemporaryActivityClockMapper"
>
<resultMap
id=
"clockMap"
type=
"com.wangxiaolu.export.mapper.entity.TemporaryActivityClockDO"
>
<result
property=
"temporaryId"
column=
"temporary_id"
jdbcType=
"BIGINT"
/>
<result
property=
"createDate"
column=
"create_date"
jdbcType=
"VARCHAR"
/>
<collection
property=
"photoList"
ofType=
"com.wangxiaolu.export.mapper.entity.TemporaryActivityPhotoDO"
>
<result
property=
"type"
column=
"type"
jdbcType=
"INTEGER"
/>
<result
property=
"photoUrl"
column=
"photo_url"
jdbcType=
"VARCHAR"
/>
</collection>
</resultMap>
<select
id=
"findClockPhotoList"
resultMap=
"clockMap"
>
select ar.temporary_id temporary_id,
ar.create_date create_date,
ap.type type,
ap.photo_url photo_url
from temporary_activity_reported ar
inner join temporary_activity_clock ac
on ar.temporary_id = ac.temporary_id and ar.create_date = ac.create_date
inner join temporary_activity_photo ap on ac.id = ap.clock_id
where (ar.create_time between #{params.createDateStart} and #{params.createDateEnd})
and ap.is_delete = 1;
</select>
</mapper>
src/main/resources/mapper/TemporaryActivityPhotoMapper.xml
0 → 100644
浏览文件 @
cdac5cb8
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.wangxiaolu.export.mapper.TemporaryActivityPhotoMapper"
>
<resultMap
id=
"BaseResultMap"
type=
"com.wangxiaolu.export.mapper.entity.TemporaryActivityPhotoDO"
>
<result
property=
"reportedId"
column=
"reported_id"
jdbcType=
"BIGINT"
/>
<result
property=
"clockId"
column=
"clock_id"
jdbcType=
"BIGINT"
/>
<result
property=
"type"
column=
"type"
jdbcType=
"INTEGER"
/>
<result
property=
"photoUrl"
column=
"photo_url"
jdbcType=
"VARCHAR"
/>
</resultMap>
<select
id=
"findActivityPhotos"
resultMap=
"BaseResultMap"
>
select reported_id, type, photo_url
from temporary_activity_photo
where is_delete = 1
and reported_id in (45, 46, 47);
</select>
</mapper>
src/main/resources/mapper/TemporaryActivityReportedMapper.xml
0 → 100644
浏览文件 @
cdac5cb8
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.wangxiaolu.export.mapper.TemporaryActivityReportedMapper"
>
<resultMap
id=
"BaseResultMap"
type=
"com.wangxiaolu.export.mapper.entity.TemporaryActivityReportedDO"
>
<id
property=
"id"
column=
"id"
jdbcType=
"BIGINT"
/>
<result
property=
"temporaryId"
column=
"temporary_id"
jdbcType=
"INTEGER"
/>
<result
property=
"activityPattern"
column=
"activity_pattern"
jdbcType=
"VARCHAR"
/>
<result
property=
"storeName"
column=
"store_name"
jdbcType=
"VARCHAR"
/>
<result
property=
"city"
column=
"city"
jdbcType=
"VARCHAR"
/>
<result
property=
"approveName"
column=
"approve_name"
jdbcType=
"VARCHAR"
/>
<result
property=
"createDate"
column=
"create_date"
jdbcType=
"CHAR"
/>
<result
property=
"lineName"
column=
"line_name"
jdbcType=
"VARCHAR"
/>
<result
property=
"orgName"
column=
"org_name"
jdbcType=
"VARCHAR"
/>
</resultMap>
<select
id=
"findList"
resultMap=
"BaseResultMap"
>
select ar.id,
ar.temporary_id,
ar.approver_id,
ar.approve_name,
ar.city,
ar.create_date,
ar.store_id,
ar.store_name,
ar.activity_pattern,
ps.line_name,
qd.org_name
from temporary_activity_reported ar
left join promotion_store ps on ar.store_id = ps.id
left join qince_employee qe on ar.approver_id = qe.qc_id
left join qince_department qd on qe.waiqin365_org_id = qd.qc_id
where (ar.create_time between #{params.createDateStart} and #{params.createDateEnd})
and (qd.org_name like '%战区' or qd.org_name = '重客运营部');
</select>
</mapper>
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论