parent
c20898fe81
commit
daf76a07bb
42 changed files with 501 additions and 258 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,11 @@ |
|||||||
|
package com.daqing.framework.utils.excel; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 异常 |
||||||
|
*/ |
||||||
|
public class ExcelException extends RuntimeException { |
||||||
|
public ExcelException(String message) { |
||||||
|
super(message); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
package com.daqing.framework.utils.excel; |
||||||
|
|
||||||
|
import com.alibaba.excel.context.AnalysisContext; |
||||||
|
import com.alibaba.excel.event.AnalysisEventListener; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* 监听 |
||||||
|
*/ |
||||||
|
public class ExcelListener extends AnalysisEventListener { |
||||||
|
|
||||||
|
//自定义用于暂时存储data。
|
||||||
|
//可以通过实例获取该值
|
||||||
|
private List<Object> datas = new ArrayList<>(); |
||||||
|
|
||||||
|
/** |
||||||
|
* 通过 AnalysisContext 对象还可以获取当前 sheet,当前行等数据 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void invoke(Object object, AnalysisContext context) { |
||||||
|
//数据存储到list,供批量处理,或后续自己业务逻辑处理。
|
||||||
|
datas.add(object); |
||||||
|
//根据业务自行 do something
|
||||||
|
doSomething(); |
||||||
|
|
||||||
|
/* |
||||||
|
如数据过大,可以进行定量分批处理 |
||||||
|
if(datas.size()<=100){ |
||||||
|
datas.add(object); |
||||||
|
}else { |
||||||
|
doSomething(); |
||||||
|
datas = new ArrayList<Object>(); |
||||||
|
} |
||||||
|
*/ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据业务自行实现该方法 |
||||||
|
*/ |
||||||
|
private void doSomething() { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doAfterAllAnalysed(AnalysisContext context) { |
||||||
|
/* |
||||||
|
datas.clear(); |
||||||
|
解析结束销毁不用的资源 |
||||||
|
*/ |
||||||
|
} |
||||||
|
|
||||||
|
public List<Object> getDatas() { |
||||||
|
return datas; |
||||||
|
} |
||||||
|
|
||||||
|
public void setDatas(List<Object> datas) { |
||||||
|
this.datas = datas; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,148 @@ |
|||||||
|
package com.daqing.framework.utils.excel; |
||||||
|
|
||||||
|
import com.alibaba.excel.ExcelReader; |
||||||
|
import com.alibaba.excel.ExcelWriter; |
||||||
|
import com.alibaba.excel.metadata.BaseRowModel; |
||||||
|
import com.alibaba.excel.metadata.Sheet; |
||||||
|
import com.alibaba.excel.support.ExcelTypeEnum; |
||||||
|
import org.springframework.web.multipart.MultipartFile; |
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import java.io.*; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* 基本工具类 |
||||||
|
*/ |
||||||
|
public class ExcelUtil { |
||||||
|
/** |
||||||
|
* 读取 Excel(多个 sheet) |
||||||
|
* |
||||||
|
* @param excel 文件 |
||||||
|
* @param rowModel 实体类映射,继承 BaseRowModel 类 |
||||||
|
* @return Excel 数据 list |
||||||
|
*/ |
||||||
|
public static List<Object> readExcel(MultipartFile excel, BaseRowModel rowModel) { |
||||||
|
ExcelListener excelListener = new ExcelListener(); |
||||||
|
ExcelReader reader = getReader(excel, excelListener); |
||||||
|
if (reader == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
for (Sheet sheet : reader.getSheets()) { |
||||||
|
if (rowModel != null) { |
||||||
|
sheet.setClazz(rowModel.getClass()); |
||||||
|
} |
||||||
|
reader.read(sheet); |
||||||
|
} |
||||||
|
return excelListener.getDatas(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 读取某个 sheet 的 Excel |
||||||
|
* |
||||||
|
* @param excel 文件 |
||||||
|
* @param rowModel 实体类映射,继承 BaseRowModel 类 |
||||||
|
* @param sheetNo sheet 的序号 从1开始 |
||||||
|
* @return Excel 数据 list |
||||||
|
*/ |
||||||
|
public static List<Object> readExcel(MultipartFile excel, BaseRowModel rowModel, int sheetNo) { |
||||||
|
return readExcel(excel, rowModel, sheetNo, 1); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 读取某个 sheet 的 Excel |
||||||
|
* |
||||||
|
* @param excel 文件 |
||||||
|
* @param rowModel 实体类映射,继承 BaseRowModel 类 |
||||||
|
* @param sheetNo sheet 的序号 从1开始 |
||||||
|
* @param headLineNum 表头行数,默认为1 |
||||||
|
* @return Excel 数据 list |
||||||
|
*/ |
||||||
|
public static List<Object> readExcel(MultipartFile excel, BaseRowModel rowModel, int sheetNo, |
||||||
|
int headLineNum) { |
||||||
|
ExcelListener excelListener = new ExcelListener(); |
||||||
|
ExcelReader reader = getReader(excel, excelListener); |
||||||
|
if (reader == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
reader.read(new Sheet(sheetNo, headLineNum, rowModel.getClass())); |
||||||
|
return excelListener.getDatas(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 导出 Excel :一个 sheet,带表头 |
||||||
|
* |
||||||
|
* @param response HttpServletResponse |
||||||
|
* @param list 数据 list,每个元素为一个 BaseRowModel |
||||||
|
* @param fileName 导出的文件名 |
||||||
|
* @param sheetName 导入文件的 sheet 名 |
||||||
|
* @param object 映射实体类,Excel 模型 |
||||||
|
*/ |
||||||
|
public static void writeExcel(HttpServletResponse response, List<? extends BaseRowModel> list, |
||||||
|
String fileName, String sheetName, BaseRowModel object) { |
||||||
|
ExcelWriter writer = new ExcelWriter(getOutputStream(fileName, response), ExcelTypeEnum.XLSX); |
||||||
|
Sheet sheet = new Sheet(1, 0, object.getClass()); |
||||||
|
sheet.setSheetName(sheetName); |
||||||
|
writer.write(list, sheet); |
||||||
|
writer.finish(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 导出 Excel :多个 sheet,带表头 |
||||||
|
* |
||||||
|
* @param response HttpServletResponse |
||||||
|
* @param list 数据 list,每个元素为一个 BaseRowModel |
||||||
|
* @param fileName 导出的文件名 |
||||||
|
* @param sheetName 导入文件的 sheet 名 |
||||||
|
* @param object 映射实体类,Excel 模型 |
||||||
|
*/ |
||||||
|
public static ExcelWriterFactroy writeExcelWithSheets(HttpServletResponse response, List<? extends BaseRowModel> list, |
||||||
|
String fileName, String sheetName, BaseRowModel object) { |
||||||
|
ExcelWriterFactroy writer = new ExcelWriterFactroy(getOutputStream(fileName, response), ExcelTypeEnum.XLSX); |
||||||
|
Sheet sheet = new Sheet(1, 0, object.getClass()); |
||||||
|
sheet.setSheetName(sheetName); |
||||||
|
writer.write(list, sheet); |
||||||
|
return writer; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 导出文件时为Writer生成OutputStream |
||||||
|
*/ |
||||||
|
private static OutputStream getOutputStream(String fileName, HttpServletResponse response) { |
||||||
|
//创建本地文件
|
||||||
|
String filePath = fileName + ".xlsx"; |
||||||
|
File dbfFile = new File(filePath); |
||||||
|
try { |
||||||
|
if (!dbfFile.exists() || dbfFile.isDirectory()) { |
||||||
|
dbfFile.createNewFile(); |
||||||
|
} |
||||||
|
fileName = new String(filePath.getBytes(), "ISO-8859-1"); |
||||||
|
response.addHeader("Content-Disposition", "filename=" + fileName); |
||||||
|
return response.getOutputStream(); |
||||||
|
} catch (IOException e) { |
||||||
|
throw new ExcelException("创建文件失败!"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 返回 ExcelReader |
||||||
|
* |
||||||
|
* @param excel 需要解析的 Excel 文件 |
||||||
|
* @param excelListener new ExcelListener() |
||||||
|
*/ |
||||||
|
private static ExcelReader getReader(MultipartFile excel, |
||||||
|
ExcelListener excelListener) { |
||||||
|
String filename = excel.getOriginalFilename(); |
||||||
|
if (filename == null || (!filename.toLowerCase().endsWith(".xls") && !filename.toLowerCase().endsWith(".xlsx"))) { |
||||||
|
throw new ExcelException("文件格式错误!"); |
||||||
|
} |
||||||
|
InputStream inputStream; |
||||||
|
try { |
||||||
|
inputStream = new BufferedInputStream(excel.getInputStream()); |
||||||
|
return new ExcelReader(inputStream, null, excelListener, false); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
package com.daqing.framework.utils.excel; |
||||||
|
|
||||||
|
import com.alibaba.excel.ExcelWriter; |
||||||
|
import com.alibaba.excel.metadata.BaseRowModel; |
||||||
|
import com.alibaba.excel.metadata.Sheet; |
||||||
|
import com.alibaba.excel.support.ExcelTypeEnum; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.io.OutputStream; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* 多sheet工具类 |
||||||
|
*/ |
||||||
|
public class ExcelWriterFactroy extends ExcelWriter { |
||||||
|
private OutputStream outputStream; |
||||||
|
private int sheetNo = 1; |
||||||
|
|
||||||
|
public ExcelWriterFactroy(OutputStream outputStream, ExcelTypeEnum typeEnum) { |
||||||
|
super(outputStream, typeEnum); |
||||||
|
this.outputStream = outputStream; |
||||||
|
} |
||||||
|
|
||||||
|
public ExcelWriterFactroy write(List<? extends BaseRowModel> list, String sheetName, |
||||||
|
BaseRowModel object) { |
||||||
|
this.sheetNo++; |
||||||
|
try { |
||||||
|
Sheet sheet = new Sheet(sheetNo, 0, object.getClass()); |
||||||
|
sheet.setSheetName(sheetName); |
||||||
|
this.write(list, sheet); |
||||||
|
} catch (Exception ex) { |
||||||
|
ex.printStackTrace(); |
||||||
|
try { |
||||||
|
outputStream.flush(); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void finish() { |
||||||
|
super.finish(); |
||||||
|
try { |
||||||
|
outputStream.flush(); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -1,4 +1,4 @@ |
|||||||
package com.daqing.framework.utils; |
package com.daqing.framework.utils.oss; |
||||||
|
|
||||||
import com.aliyun.oss.OSSClient; |
import com.aliyun.oss.OSSClient; |
||||||
import com.aliyun.oss.model.PutObjectRequest; |
import com.aliyun.oss.model.PutObjectRequest; |
@ -1,29 +0,0 @@ |
|||||||
package com.daqing.framework.utils.poi; |
|
||||||
|
|
||||||
/** |
|
||||||
* @auther River |
|
||||||
* @date 2020/9/16 17:10 |
|
||||||
*/ |
|
||||||
import java.lang.annotation.ElementType; |
|
||||||
import java.lang.annotation.Retention; |
|
||||||
import java.lang.annotation.RetentionPolicy; |
|
||||||
import java.lang.annotation.Target; |
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME) |
|
||||||
@Target(ElementType.FIELD) |
|
||||||
public @interface ExcelAttribute { |
|
||||||
/** |
|
||||||
* 对应的列名称 |
|
||||||
*/ |
|
||||||
String name() default ""; |
|
||||||
|
|
||||||
/** |
|
||||||
* excel列的索引 |
|
||||||
*/ |
|
||||||
int sort(); |
|
||||||
|
|
||||||
/** |
|
||||||
* 字段类型对应的格式 |
|
||||||
*/ |
|
||||||
String format() default ""; |
|
||||||
} |
|
@ -1,87 +0,0 @@ |
|||||||
package com.daqing.framework.utils.poi; |
|
||||||
|
|
||||||
import lombok.Data; |
|
||||||
import org.apache.poi.ss.usermodel.Cell; |
|
||||||
import org.apache.poi.ss.usermodel.CellStyle; |
|
||||||
import org.apache.poi.ss.usermodel.Row; |
|
||||||
import org.apache.poi.ss.usermodel.Sheet; |
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
|
||||||
import javax.servlet.http.HttpServletResponse; |
|
||||||
|
|
||||||
import java.io.InputStream; |
|
||||||
import java.lang.reflect.Field; |
|
||||||
import java.net.URLEncoder; |
|
||||||
import java.util.List; |
|
||||||
import java.util.concurrent.atomic.AtomicInteger; |
|
||||||
|
|
||||||
/** |
|
||||||
* 导出Excel工具类 |
|
||||||
* 基于模板打印的方式导出: |
|
||||||
*/ |
|
||||||
@Data |
|
||||||
public class ExcelExportUtil<T> { |
|
||||||
|
|
||||||
private int rowIndex; //写入数据的起始行
|
|
||||||
private int styleIndex; //需要提取的样式所在的行号
|
|
||||||
private Class clazz; //对象的字节码
|
|
||||||
private Field fields[]; //对象中的所有属性
|
|
||||||
|
|
||||||
public ExcelExportUtil(Class clazz, int rowIndex, int styleIndex) { |
|
||||||
this.clazz = clazz; |
|
||||||
this.rowIndex = rowIndex; |
|
||||||
this.styleIndex = styleIndex; |
|
||||||
fields = clazz.getDeclaredFields(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 基于注解导出 |
|
||||||
* 参数: |
|
||||||
* response: |
|
||||||
* InputStream:模板的输入流 |
|
||||||
* objs:数据 |
|
||||||
* fileName:生成的文件名 |
|
||||||
*/ |
|
||||||
public void export(HttpServletResponse response, InputStream is, List<T> objs, String fileName) throws Exception { |
|
||||||
|
|
||||||
//1.根据模板创建工作簿
|
|
||||||
XSSFWorkbook workbook = new XSSFWorkbook(is); |
|
||||||
//2.读取工作表
|
|
||||||
Sheet sheet = workbook.getSheetAt(0); |
|
||||||
//3.提取公共的样式
|
|
||||||
CellStyle[] styles = getTemplateStyles(sheet.getRow(styleIndex)); |
|
||||||
//4.根据数据创建每一行和每一个单元格的数据2
|
|
||||||
AtomicInteger datasAi = new AtomicInteger(rowIndex); //数字
|
|
||||||
for (T t : objs) { |
|
||||||
//datasAi.getAndIncrement() :获取数字,并++ i++
|
|
||||||
Row row = sheet.createRow(datasAi.getAndIncrement()); |
|
||||||
for (int i = 0; i < styles.length; i++) { |
|
||||||
Cell cell = row.createCell(i); |
|
||||||
cell.setCellStyle(styles[i]); |
|
||||||
for (Field field : fields) { |
|
||||||
if (field.isAnnotationPresent(ExcelAttribute.class)) { |
|
||||||
field.setAccessible(true); |
|
||||||
ExcelAttribute ea = field.getAnnotation(ExcelAttribute.class); |
|
||||||
if (i == ea.sort()) { |
|
||||||
if (field.get(t) != null) { |
|
||||||
cell.setCellValue(field.get(t).toString()); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
fileName = URLEncoder.encode(fileName, "UTF-8"); |
|
||||||
response.setContentType("application/octet-stream"); |
|
||||||
response.setHeader("content-disposition", "attachment;filename=" + new String(fileName.getBytes("ISO8859-1"))); |
|
||||||
response.setHeader("filename", fileName); |
|
||||||
workbook.write(response.getOutputStream()); |
|
||||||
} |
|
||||||
|
|
||||||
CellStyle[] getTemplateStyles(Row row) { |
|
||||||
CellStyle[] styles = new CellStyle[row.getLastCellNum()]; |
|
||||||
for (int i = 0; i < row.getLastCellNum(); i++) { |
|
||||||
styles[i] = row.getCell(i).getCellStyle(); |
|
||||||
} |
|
||||||
return styles; |
|
||||||
} |
|
||||||
} |
|
@ -1,122 +0,0 @@ |
|||||||
package com.daqing.framework.utils.poi; |
|
||||||
|
|
||||||
import org.apache.poi.ss.usermodel.Cell; |
|
||||||
import org.apache.poi.ss.usermodel.DateUtil; |
|
||||||
import org.apache.poi.ss.usermodel.Row; |
|
||||||
import org.apache.poi.ss.usermodel.Sheet; |
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
|
||||||
|
|
||||||
import java.io.InputStream; |
|
||||||
import java.lang.reflect.Field; |
|
||||||
import java.math.BigDecimal; |
|
||||||
import java.text.SimpleDateFormat; |
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.Date; |
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
public class ExcelImportUtil<T> { |
|
||||||
|
|
||||||
private Class clazz; |
|
||||||
private Field fields[]; |
|
||||||
|
|
||||||
public ExcelImportUtil(Class clazz) { |
|
||||||
this.clazz = clazz; |
|
||||||
fields = clazz.getDeclaredFields(); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 基于注解读取excel |
|
||||||
*/ |
|
||||||
public List<T> readExcel(InputStream is, int rowIndex, int cellIndex) { |
|
||||||
List<T> list = new ArrayList<>(); |
|
||||||
T entity = null; |
|
||||||
try { |
|
||||||
XSSFWorkbook workbook = new XSSFWorkbook(is); |
|
||||||
Sheet sheet = workbook.getSheetAt(0); |
|
||||||
// 不准确
|
|
||||||
// int rowLength = sheet.getLastRowNum();
|
|
||||||
// System.out.println(sheet.getLastRowNum());
|
|
||||||
for (int rowNum = rowIndex; rowNum <= sheet.getLastRowNum(); rowNum++) { |
|
||||||
Row row = sheet.getRow(rowNum); |
|
||||||
entity = (T) clazz.newInstance(); |
|
||||||
// System.out.println(row.getLastCellNum());
|
|
||||||
for (int j = cellIndex; j < row.getLastCellNum(); j++) { |
|
||||||
Cell cell = row.getCell(j); |
|
||||||
for (Field field : fields) { |
|
||||||
if (field.isAnnotationPresent(ExcelAttribute.class)) { |
|
||||||
field.setAccessible(true); |
|
||||||
ExcelAttribute ea = field.getAnnotation(ExcelAttribute.class); |
|
||||||
if (j == ea.sort()) { |
|
||||||
field.set(entity, covertAttrType(field, cell)); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
Field field = entity.getClass().getDeclaredField("index"); |
|
||||||
field.setAccessible(true); |
|
||||||
field.set(entity, rowNum); |
|
||||||
list.add(entity); |
|
||||||
} |
|
||||||
} catch (Exception e) { |
|
||||||
e.printStackTrace(); |
|
||||||
} |
|
||||||
return list; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 类型转换 将cell 单元格格式转为 字段类型 |
|
||||||
*/ |
|
||||||
private Object covertAttrType(Field field, Cell cell) throws Exception { |
|
||||||
String fieldType = field.getType().getSimpleName(); |
|
||||||
if ("String".equals(fieldType)) { |
|
||||||
return getValue(cell); |
|
||||||
} else if ("Date".equals(fieldType)) { |
|
||||||
return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(getValue(cell)); |
|
||||||
} else if ("int".equals(fieldType) || "Integer".equals(fieldType)) { |
|
||||||
return Integer.parseInt(getValue(cell)); |
|
||||||
} else if ("double".equals(fieldType) || "Double".equals(fieldType)) { |
|
||||||
return Double.parseDouble(getValue(cell)); |
|
||||||
} else { |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* 格式转为String |
|
||||||
* |
|
||||||
* @param cell |
|
||||||
* @return |
|
||||||
*/ |
|
||||||
public String getValue(Cell cell) { |
|
||||||
if (cell == null) { |
|
||||||
return ""; |
|
||||||
} |
|
||||||
switch (cell.getCellType()) { |
|
||||||
case STRING: |
|
||||||
return cell.getRichStringCellValue().getString().trim(); |
|
||||||
case NUMERIC: |
|
||||||
if (DateUtil.isCellDateFormatted(cell)) { |
|
||||||
Date dt = DateUtil.getJavaDate(cell.getNumericCellValue()); |
|
||||||
return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(dt); |
|
||||||
} else { |
|
||||||
// 防止数值变成科学计数法
|
|
||||||
String strCell = ""; |
|
||||||
Double num = cell.getNumericCellValue(); |
|
||||||
BigDecimal bd = new BigDecimal(num.toString()); |
|
||||||
if (bd != null) { |
|
||||||
strCell = bd.toPlainString(); |
|
||||||
} |
|
||||||
// 去除 浮点型 自动加的 .0
|
|
||||||
if (strCell.endsWith(".0")) { |
|
||||||
strCell = strCell.substring(0, strCell.indexOf(".")); |
|
||||||
} |
|
||||||
return strCell; |
|
||||||
} |
|
||||||
case BOOLEAN: |
|
||||||
return String.valueOf(cell.getBooleanCellValue()); |
|
||||||
default: |
|
||||||
return ""; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue