Commit 6849600f by kk

导excel数据

parent da13073c
......@@ -99,6 +99,12 @@
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
......
......@@ -212,6 +212,17 @@ public class SyncProductAudit implements Serializable {
@TableField("audit_remark")
private String auditRemark;
@ApiModelProperty(value = "是否定制产品")
private Integer isCustomProduct;
public Integer getIsCustomProduct() {
return isCustomProduct;
}
public void setIsCustomProduct(Integer isCustomProduct) {
this.isCustomProduct = isCustomProduct;
}
public Long getId() {
return id;
}
......
package cn.kk.spring_simple_operation.mapper;
import cn.kk.spring_simple_operation.entity.SyncProductAudit;
import cn.kk.spring_simple_operation.model.ExportPhotographerNameVO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
......@@ -20,4 +21,8 @@ public interface SyncProductAuditMapper extends BaseMapper<SyncProductAudit> {
List<String> groupSkuSolarTerm_1();
List<String> groupSkuSolarTerm_Q1Q2();
List<ExportPhotographerNameVO> selectIsCustomProdduct();
List<ExportPhotographerNameVO> selectIsCustomProdductPlan();
}
package cn.kk.spring_simple_operation.model;
import cn.kk.spring_simple_operation.utils.Excel;
/**
* @author kk
* @date 2025/2/6
*/
public class ExportPhotographerNameVO {
@Excel(name = "SKU")
private String sku;
@Excel(name = "标题")
private String title;
@Excel(name = "节气")
private String solarName;
@Excel(name = "开发")
private String developer;
@Excel(name = "策划")
private String planName;
@Excel(name = "摄影")
private String photographerName;
@Excel(name = "是否定制产品")
private String isCustomProduct;
public String getSku() {
return sku;
}
public void setSku(String sku) {
this.sku = sku;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSolarName() {
return solarName;
}
public void setSolarName(String solarName) {
this.solarName = solarName;
}
public String getDeveloper() {
return developer;
}
public void setDeveloper(String developer) {
this.developer = developer;
}
public String getPlanName() {
return planName;
}
public void setPlanName(String planName) {
this.planName = planName;
}
public String getPhotographerName() {
return photographerName;
}
public void setPhotographerName(String photographerName) {
this.photographerName = photographerName;
}
public String getIsCustomProduct() {
return isCustomProduct;
}
public void setIsCustomProduct(String isCustomProduct) {
this.isCustomProduct = isCustomProduct;
}
}
package cn.kk.spring_simple_operation.utils;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.math.BigDecimal;
/**
* 自定义导出Excel数据注解
*
* @author Devin
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Excel {
/**
* 导出时在excel中排序
*/
public int sort() default Integer.MAX_VALUE;
/**
* 导出到Excel中的名字.
*/
public String name() default "";
/**
* 日期格式, 如: yyyy-MM-dd
*/
public String dateFormat() default "";
/**
* 读取内容转表达式 (如: 0=男,1=女,2=未知)
*/
public String readConverterExp() default "";
/**
* 分隔符,读取字符串组内容
*/
public String separator() default ",";
/**
* BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化)
*/
public int scale() default -1;
/**
* BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN
*/
public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
/**
* 导出类型(0数字 1字符串)
*/
public ColumnType cellType() default ColumnType.STRING;
/**
* 导出时在excel中每个列的高度 单位为字符
*/
public double height() default 14;
/**
* 导出时在excel中每个列的宽 单位为字符
*/
public double width() default 16;
/**
* 文字后缀,如% 90 变成90%
*/
public String suffix() default "";
/**
* 当值为空时,字段的默认值
*/
public String defaultValue() default "";
/**
* 提示信息
*/
public String prompt() default "";
/**
* 设置只能选择不能输入的列内容.
*/
public String[] combo() default {};
/**
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
*/
public boolean isExport() default true;
/**
* 另一个类中的属性名称,支持多级获取,以小数点隔开
*/
public String targetAttr() default "";
/**
* 是否自动统计数据,在最后追加一行统计数据总和
*/
public boolean isStatistics() default false;
/**
* 导出字段对齐方式(0:默认;1:靠左;2:居中;3:靠右)
*/
Align align() default Align.AUTO;
/**
* 导出的文本的颜色 取自 IndexedColors 中 index 的值
*/
public short color() default -1;
/**
* 导出的文本显示指定颜色时的数据范围 min
*/
public long colorMin() default 0;
/**
* 导出的文本显示指定颜色时的数据范围 max
*/
public long colorMax() default 0;
public enum Align {
AUTO(0), LEFT(1), CENTER(2), RIGHT(3);
private final int value;
Align(int value) {
this.value = value;
}
public int value() {
return this.value;
}
}
/**
* 字段类型(0:导出导入;1:仅导出;2:仅导入)
*/
Type type() default Type.ALL;
public enum Type {
ALL(0), EXPORT(1), IMPORT(2);
private final int value;
Type(int value) {
this.value = value;
}
public int value() {
return this.value;
}
}
public enum ColumnType {
NUMERIC(0), STRING(1), IMAGE(2);
private final int value;
ColumnType(int value) {
this.value = value;
}
public int value() {
return this.value;
}
}
}
\ No newline at end of file
package cn.kk.spring_simple_operation.utils;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Excel注解集
*
* @author Devin
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Excels
{
Excel[] value();
}
\ No newline at end of file
package cn.kk.spring_simple_operation.utils;
import org.apache.poi.util.IOUtils;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import java.util.List;
/**
* 图片处理工具类
*/
public class ImageUtils {
public static byte[] getImage(String imagePath) {
InputStream is = getFile(imagePath);
try {
return IOUtils.toByteArray(is);
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
IOUtils.closeQuietly(is);
}
}
public static InputStream getFile(String imagePath) {
try {
byte[] result = readFile(imagePath);
result = Arrays.copyOf(result, result.length);
return new ByteArrayInputStream(result);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 读取文件为字节数据
*
* @param url 地址
* @return 字节数据
*/
public static byte[] readFile(String url) {
InputStream in = null;
ByteArrayOutputStream baos = null;
try {
// 网络地址
URL urlObj = new URL(url);
URLConnection urlConnection = urlObj.openConnection();
urlConnection.setConnectTimeout(30 * 1000);
urlConnection.setReadTimeout(60 * 1000);
urlConnection.setDoInput(true);
in = urlConnection.getInputStream();
return IOUtils.toByteArray(in);
} catch (Exception e) {
e.getMessage();
return null;
} finally {
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(baos);
}
}
/**
* 竖着合并多个图片
*
* @param images
*/
public static BufferedImage mergeImg(List<BufferedImage> images) {
Integer width = images.stream().map(BufferedImage::getWidth).max(Integer::compareTo).orElse(0);
Integer height = images.stream().map(BufferedImage::getHeight).reduce(Integer::sum).orElse(0);
BufferedImage merge = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = merge.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
Integer tmpH = 0;
for (BufferedImage image : images) {
g2d.drawImage(image, 0, tmpH, image.getWidth(), image.getHeight(), null);
tmpH += image.getHeight();
}
return merge;
}
/**
* 修改图片分辨率
*
* @param bufferedImage
* @param WIDTH
* @param HEIGHT
*/
public BufferedImage scaleImage(BufferedImage bufferedImage, int WIDTH, int HEIGHT) {
BufferedImage bi = null;
try {
bi = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bi.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(bufferedImage, 0, 0, WIDTH, HEIGHT, null);
} catch (Exception e) {
return null;
}
return bi;
}
}
package cn.kk.spring_simple_operation.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 类型转换工具类
*/
public class TypeUtils {
/**
* 普通对象转为jsonObj 对象
*/
public static <T> JSONObject castToJsonObj(Object value) {
if (value instanceof JSONObject) {
return (JSONObject) value;
}
if (value instanceof Map) {
return new JSONObject((Map) value);
}
if (value instanceof String) {
return JSON.parseObject((String) value);
}
return (JSONObject) JSON.toJSON(value);
}
/**
* 普通对象转为 jsonArr
*/
public static JSONArray castToJsonArr(Object value) {
if (value instanceof JSONArray) {
return (JSONArray) value;
}
if (value instanceof List) {
return new JSONArray((List) value);
}
if (value instanceof String) {
return (JSONArray) JSON.parse((String) value);
}
return (JSONArray) JSON.toJSON(value);
}
/**
* 判断obj是否是否是基本数据类型及其包装类
*/
public static boolean isWrapper(Object obj) {
try {
if (obj == null) return false;
Field type = obj.getClass().getField("TYPE");
return ((Class) type.get(null)).isPrimitive();
} catch (Exception e) {
return false;
}
}
/**
* 将字符串转换为set集合
*
* @param key
* @param clz
* @param <T>
*/
public static <T> Set<T> jsonToSet(String key, Class<T> clz) {
List<T> list = jsonToList(key, clz);
if (CollectionUtils.isEmpty(list)) {
return null;
}
return new HashSet<>(list);
}
/**
* 将字符串转换为set集合
*
* @param key
* @param clz
* @param <T>
* @return
*/
public static <T> List<T> jsonToList(String key, Class<T> clz) {
if (org.apache.commons.lang3.StringUtils.isNotBlank(key)) {
List<T> ts = JSON.parseArray(key, clz);
return ts;
}
return null;
}
/**
* 转换为字符串<br>
* 如果给定的值为null,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static String toStr(Object value, String defaultValue) {
if (null == value) {
return defaultValue;
}
if (value instanceof String) {
return (String) value;
}
if (value instanceof Number) {
return value.toString();
}
// JSON.toJSONString 数字会多一个引号
return JSON.toJSONString(value);
}
/**
* 转换为字符串<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static String toStr(Object value) {
return toStr(value, null);
}
/**
* 转换为int<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static Integer toInt(Object value, Integer defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Integer) {
return (Integer) value;
}
if (value instanceof Number) {
return ((Number) value).intValue();
}
final String valueStr = toStr(value, null);
if (StringUtils.isEmpty(valueStr)) {
return defaultValue;
}
try {
return Integer.parseInt(valueStr.trim());
} catch (Exception e) {
return defaultValue;
}
}
/**
* 转换为int<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static Integer toInt(Object value) {
return toInt(value, null);
}
/**
* 转换为double<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static Double toDouble(Object value, Double defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Double) {
return (Double) value;
}
if (value instanceof Number) {
return ((Number) value).doubleValue();
}
final String valueStr = toStr(value, null);
if (StringUtils.isEmpty(valueStr)) {
return defaultValue;
}
try {
// 支持科学计数法
return new BigDecimal(valueStr.trim()).doubleValue();
} catch (Exception e) {
return defaultValue;
}
}
/**
* 转换为double<br>
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static Double toDouble(Object value) {
return toDouble(value, null);
}
/**
* 转换为long<br>
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static Long toLong(Object value) {
return toLong(value, null);
}
/**
* 转换为long<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static Long toLong(Object value, Long defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Long) {
return (Long) value;
}
if (value instanceof Number) {
return ((Number) value).longValue();
}
final String valueStr = toStr(value, null);
if (StringUtils.isEmpty(valueStr)) {
return defaultValue;
}
try {
// 支持科学计数法
return new BigDecimal(valueStr.trim()).longValue();
} catch (Exception e) {
return defaultValue;
}
}
/**
* 转换为Float<br>
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static Float toFloat(Object value) {
return toFloat(value, null);
}
/**
* 转换为Float<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static Float toFloat(Object value, Float defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Float) {
return (Float) value;
}
if (value instanceof Number) {
return ((Number) value).floatValue();
}
final String valueStr = toStr(value, null);
if (StringUtils.isEmpty(valueStr)) {
return defaultValue;
}
try {
return Float.parseFloat(valueStr.trim());
} catch (Exception e) {
return defaultValue;
}
}
/**
* 转换为BigDecimal<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static BigDecimal toBigDecimal(Object value) {
return toBigDecimal(value, null);
}
/**
* 转换为BigDecimal<br>
* 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof BigDecimal) {
return (BigDecimal) value;
}
if (value instanceof Long) {
return new BigDecimal((Long) value);
}
if (value instanceof Double) {
return new BigDecimal((Double) value);
}
if (value instanceof Integer) {
return new BigDecimal((Integer) value);
}
final String valueStr = toStr(value, null);
if (StringUtils.isEmpty(valueStr)) {
return defaultValue;
}
try {
return new BigDecimal(valueStr);
} catch (Exception e) {
return defaultValue;
}
}
/**
* 转换为boolean<br>
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
* 转换失败不会报错
*
* @param value 被转换的值
* @return 结果
*/
public static Boolean toBool(Object value) {
return toBool(value, null);
}
/**
* 转换为boolean<br>
* String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值<br>
* 转换失败不会报错
*
* @param value 被转换的值
* @param defaultValue 转换错误时的默认值
* @return 结果
*/
public static Boolean toBool(Object value, Boolean defaultValue) {
if (value == null) {
return defaultValue;
}
if (value instanceof Boolean) {
return (Boolean) value;
}
String valueStr = toStr(value, null);
if (StringUtils.isEmpty(valueStr)) {
return defaultValue;
}
valueStr = valueStr.trim().toLowerCase();
switch (valueStr) {
case "true":
return true;
case "false":
return false;
case "yes":
return true;
case "ok":
return true;
case "no":
return false;
case "1":
return true;
case "0":
return false;
default:
return defaultValue;
}
}
}
......@@ -43,6 +43,57 @@
AND spp.lowest_price > 0
AND spp.thirty_day_sales > 0
</select>
<select id="selectIsCustomProdduct"
resultType="cn.kk.spring_simple_operation.model.ExportPhotographerNameVO">
SELECT
vp.sku,
vp2.title,
ssti.solar_term_name solarName,
sd.developer_title developer,
vvp.executor_name planName,
vp2.executor_name photographerName,
if(spa.is_custom_product = 1, '是', '否') is_custom_product
FROM
visual_photographer vp2
INNER JOIN visual_video_plan vvp ON vvp.id = vp2.visual_video_plan_id
INNER JOIN video_product vp ON vp.video_plan_id = vvp.id
LEFT JOIN sync_product_audit spa ON spa.sku = vp.sku
LEFT JOIN sync_solar_term_info ssti ON ssti.solar_term_id = spa.solar_term
LEFT JOIN sync_developer sd ON sd.developer_num = spa.developer_num
WHERE
vp2.is_delete = 0
AND vvp.is_delete = 0
AND vp.is_delete = 0
AND vvp.is_have_sample = 1
AND vvp.sample_arrive_time = 0
AND spa.is_custom_product = 1
GROUP BY
vp.sku
</select>
<select id="selectIsCustomProdductPlan"
resultType="cn.kk.spring_simple_operation.model.ExportPhotographerNameVO">
SELECT
vp.sku,
vvp.title,
ssti.solar_term_name solarName,
sd.developer_title developer,
vvp.executor_name planName,
IF( spa.is_custom_product = 1, '是', '否' ) is_custom_product
FROM
visual_video_plan vvp
INNER JOIN video_product vp ON vp.video_plan_id = vvp.id
LEFT JOIN sync_product_audit spa ON spa.sku = vp.sku
LEFT JOIN sync_solar_term_info ssti ON ssti.solar_term_id = spa.solar_term
LEFT JOIN sync_developer sd ON sd.developer_num = spa.developer_num
WHERE
vvp.is_delete = 0
AND vp.is_delete = 0
AND vvp.`status` = 3
AND vvp.no_handle_reason = 2
AND spa.is_custom_product = 1
GROUP BY
vp.sku
</select>
</mapper>
package cn.kk.spring_simple_operation;
import cn.kk.spring_simple_operation.mapper.SyncProductAuditMapper;
import cn.kk.spring_simple_operation.model.ExportPhotographerNameVO;
import cn.kk.spring_simple_operation.utils.ExcelUtil;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.util.List;
/**
* @author kk
* @date 2025/2/6
*/
@SpringBootTest
public class ExportPhotographerTest {
@Resource
private SyncProductAuditMapper syncProductAuditMapper;
@Test
void contextLoads() {
List<ExportPhotographerNameVO> list = syncProductAuditMapper.selectIsCustomProdduct();
ExcelUtil<ExportPhotographerNameVO> util = new ExcelUtil<>(ExportPhotographerNameVO.class);
util.exportExcelFile(list, "有样品但是未到样的任务");
}
@Test
void contextLoad_2() {
List<ExportPhotographerNameVO> list = syncProductAuditMapper.selectIsCustomProdductPlan();
ExcelUtil<ExportPhotographerNameVO> util = new ExcelUtil<>(ExportPhotographerNameVO.class);
util.exportExcelFile(list, "断货无样品");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment