1、pom中引入jar包
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>RELEASE</version>
</dependency>2、工具类
package com.cc.fastdfs.utils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class ExcelUtil {
/**
* 导入
*/
public static <T> List<T> importExcel(MultipartFile file, Class<T> tClass){
List<T> list = new ArrayList<>();
try {
//获取文件名称
String fileName = file.getOriginalFilename();
//获取输入流
InputStream in = file.getInputStream();
Workbook workbook = WorkbookFactory.create(in);
//获取第一张工作表
Sheet sheet = workbook.getSheetAt(0);
//从第二行开始获取
for (int i = 1; i < sheet.getPhysicalNumberOfRows(); i++) {
//创建实例对象:JDK9以前class.newInstance()过时,可以使用以下方法
T dto = tClass.getDeclaredConstructor().newInstance();
//循环获取工作表的每一行
Row sheetRow = sheet.getRow(i);
//循环获取列
//getLastCellNum:获取最后一个不为空的是第几列
//getPhysicalNumberOfCells:获取不为空的列数,所以此处使用getLastCellNum
for (int j = 0; j < sheetRow.getLastCellNum(); j++) {
//获取实体类的所有属性
Field[] fields = tClass.getDeclaredFields();
//获取列对应的属性
Field field = fields[j];
//获取属性的名称
String name = field.getName();
//获得字段类型
Type genericType = field.getGenericType();
//获取字段的类型
Class<?> type = tClass.getDeclaredField(name).getType();
// 首字母大写
String replace = name.substring(0, 1).toUpperCase() + name.substring(1);
//获得set方法
Method method = tClass.getMethod("set" + replace, type);
//获取的列
Cell cell = sheetRow.getCell(j);
//获取属性类型进行判断获取value。同时给对象dto参数赋值,
// 两种获取字段类型都可以进行类型判断,此处用的是genericType,导出用的是type
if (cell!=null){
if("class java.lang.String".equals(genericType.toString())){
String stringCellValue = cell.getStringCellValue();
//执行set方法放入对应的value值
method.invoke(dto, stringCellValue);
System.out.println("数据"+j+":"+stringCellValue);
}
//如果是数字类型
if ("class java.lang.Integer".equals(genericType.toString())){
Integer numericCellValue = (int)cell.getNumericCellValue();
//执行set方法放入对应的value值
method.invoke(dto, numericCellValue);
System.out.println("数据"+j+":"+numericCellValue);
}
//如果是数字类型
if ("class java.lang.Long".equals(genericType.toString())){
Long numericCellValue = (long)cell.getNumericCellValue();
//执行set方法放入对应的value值
method.invoke(dto, numericCellValue);
System.out.println("数据"+j+":"+numericCellValue);
}
}
}
//将装有每一列的集合装入大集合
list.add(dto);
//关闭资源
workbook.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
/**
* 导出excel
* @author cc
* @date 2021/5/20 16:48
* @param response
* @param data 数据
* @param sheetName
* @param fileName
* @param titleNames
*/
public static <T> void exportExcel(HttpServletResponse response, List<T> data, Class<T> tClass, String sheetName, String fileName, String[] titleNames ) {
System.out.println("导出解析开始");
try {
//实例化HSSFWorkbook
HSSFWorkbook workbook = new HSSFWorkbook();
//创建一个Excel表单,参数为sheet的名字
HSSFSheet sheet = workbook.createSheet(sheetName);
//设置表头 此处为了方便,直接手动设置的表头集合,还可以是用自定义注解,在实体类上进行标注,解析后设置表头
setTitle(workbook, sheet, titleNames);
//设置单元格并赋值
setData(sheet, data, tClass);
//设置浏览器下载
setBrowser(response, workbook, fileName);
System.out.println("导出解析成功!");
} catch (Exception e) {
System.out.println("导出解析失败!");
e.printStackTrace();
}
}
/**
* 方法名:setTitle
* 功能:设置表头
* @param workbook
* @param sheet
* @param str
*/
private static void setTitle(HSSFWorkbook workbook, HSSFSheet sheet, String[] str) {
try {
HSSFRow row = sheet.createRow(0);
//设置列宽,setColumnWidth的第二个参数要乘以256,这个参数的单位是1/256个字符宽度
for (int i = 0; i <= str.length; i++) {
sheet.setColumnWidth(i, 15 * 256);
}
//设置为居中加粗,格式化时间格式
HSSFCellStyle style = workbook.createCellStyle();
HSSFFont font = workbook.createFont();
font.setBold(true);
style.setFont(font);
style.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));
//创建表头名称
HSSFCell cell;
for (int j = 0; j < str.length; j++) {
cell = row.createCell(j);
cell.setCellValue(str[j]);
cell.setCellStyle(style);
}
} catch (Exception e) {
System.out.println("导出时设置表头失败!");
e.printStackTrace();
}
}
/**
* 方法名:setData
* 功能:表格赋值
* @param sheet
* @param data
*/
private static <T> void setData(HSSFSheet sheet, List<T> data, Class<T> tClass) {
try{
//记录处理条数
int rowNum = 1;
for (T t : data) {
HSSFRow row = sheet.createRow(rowNum);
//获取实体类所有属性
Field[] fides = tClass.getDeclaredFields();
for (int j = 0; j < fides.length; j++) {
Field field = fides[j];
//设置属性可以访问
field.setAccessible(true);
//判断属性类型。
//获取属性的名称
String name = field.getName();
//获得字段类型
Type genericType = field.getGenericType();
//获取字段的类型
Class<?> type = tClass.getDeclaredField(name).getType();
//根据评价
if(fides[j].get(t) != null){
if (type.isAssignableFrom(String.class)) {
row.createCell(j).setCellValue((String) fides[j].get(t));
} else if (type.isAssignableFrom(int.class) || type.isAssignableFrom(Integer.class)) {
row.createCell(j).setCellValue((Integer) fides[j].get(t));
} else if (type.isAssignableFrom(Double.class) || type.isAssignableFrom(double.class)) {
row.createCell(j).setCellValue((Double) fides[j].get(t));
} else if (type.isAssignableFrom(Date.class)) {
row.createCell(j).setCellValue((Date) fides[j].get(t));
} else if (type.isAssignableFrom(long.class) || type.isAssignableFrom(Long.class)){
row.createCell(j).setCellValue((Long) fides[j].get(t));
}
}
}
rowNum++;
}
System.out.println("表格赋值成功!");
}catch (Exception e){
System.out.println("表格赋值失败!");
e.printStackTrace();
}
}
/**
* 方法名:setBrowser
* 功能:使用浏览器下载
* 描述:
* 创建人:typ
* 创建时间:2018/10/19 16:20
* 修改人:
* 修改描述:
* 修改时间:
*/
private static void setBrowser(HttpServletResponse response, HSSFWorkbook workbook, String fileName) {
try {
//清空response
response.reset();
//设置response的Header
response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
OutputStream os = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/vnd.ms-excel;charset=gb2312");
//将excel写入到输出流中
workbook.write(os);
os.flush();
os.close();
System.out.println("设置浏览器下载成功!");
} catch (Exception e) {
System.out.println("设置浏览器下载失败!");
e.printStackTrace();
}
}
}
3、service中方法调用
package com.cc.fastdfs.service;
import com.cc.fastdfs.enty.EvaluateExcel;
import com.cc.fastdfs.excel.EvaluateExcelObj;
import com.cc.fastdfs.mapper.EvaluateExcelMapper;
import com.cc.fastdfs.utils.ExcelUtil;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
* @author cc
* @data 2021年05月16日 1:22
*/
@Service
public class ExcelService {
@Autowired
private SqlSessionTemplate sqlSessionTemplate;
/**
*导出
*/
public void export(HttpServletResponse response){
List<EvaluateExcelObj> data = new ArrayList<>();
//模拟数据
for(int mm = 0 ; mm< 50 ; mm++){
EvaluateExcelObj obj = new EvaluateExcelObj();
//被评价人/
obj.setEvaluateCoverName("张三");
//编码/
obj.setEvaluateCover("111111");
//日期/
obj.setDateTime("1990-10-11 10:00:00");
//类型/
obj.setEvaluateType(1);
//其他类型文本/
obj.setTypeOthorString(null);
//评价人/
obj.setUserName("李四");
//评价场景 1:董事长见面会。 2:CEO见面会/
obj.setEvaluateScene(6);
//评价场景其他文本/
obj.setSceneOtherString("评价场景");
//评价内容/
obj.setEvaluateText("评价内容");
//计数/
obj.setJs(Long.valueOf(mm+1));
data.add(obj);
}
Class tClass = EvaluateExcelObj.class;
String sheetName = "导出数据";
String fileName = "导出";
String[] titleNames = new String[]{"被评价人","编码","日期","类型","其他类型文本","评价人", "评价场景", "评价场景其他文本", "评价内容", "计数"};
ExcelUtil.exportExcel(response, data, tClass,sheetName, fileName, titleNames);
}
/**
* excel上传
* @author cc
* @date 2021/5/20 16:53
* @param file
*/
public void uploadExcel(MultipartFile file){
//获取上传数据
List<EvaluateExcelObj> evaluateExcels = ExcelUtil.importExcel(file, EvaluateExcelObj.class);
//调用存储方法。此处为使用batch方式,批量提交。
this.insert(evaluateExcels);
System.out.println(evaluateExcels.size());
}
private void insert(List<EvaluateExcelObj> evaluateExcels){
//方式1:mybatis ExecutorType.BATCH
mybatisBatch(evaluateExcels);
}
/**
* 方式1:mybatis ExecutorType.BATCH
* @author cc
* @date 2021/5/17 17:37
* @param evaluateExcels
*/
private void mybatisBatch(List<EvaluateExcelObj> evaluateExcels){
// 新获取一个模式为BATCH,自动提交为false的session
// 如果自动提交设置为true,将无法控制提交的条数,改为最后统一提交,可能导致内存溢出
SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH,false);
//通过新的session获取mapper
EvaluateExcelMapper mapper = session.getMapper(EvaluateExcelMapper.class);
try{
for (int i =0 ; i < evaluateExcels.size() ; i++){
EvaluateExcel evaluateExcel = new EvaluateExcel();
evaluateExcel.setJs(evaluateExcels.get(i).getJs());
evaluateExcel.setEvaluateCover(evaluateExcels.get(i).getEvaluateCover());
evaluateExcel.setEvaluateCoverName(evaluateExcels.get(i).getEvaluateCoverName());
mapper.insert(evaluateExcel);
if (i % 5000 == 0 || i == evaluateExcels.size()-1){
//手动每5000个一提交,提交后无法回滚
session.commit();
//清理缓存,防止溢出
session.clearCache();
}
}
} catch (Exception e){
e.printStackTrace();
//报错回滚
session.rollback();
}finally {
session.close();
}
}
}
4、Controller调用
package com.cc.fastdfs.controller;
import com.cc.fastdfs.service.ExcelService;
import com.cc.fastdfs.utils.FileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/excel")
public class ExcelController {
@Autowired
private ExcelService excelService;
/**
* 上传
* @author cc
* @date 2021/5/21 11:14
* @param file
*/
@RequestMapping("/uploadExcel")
public void uploadExcel(MultipartFile file){
excelService.uploadExcel(file);
}
/**
* 导出
* @author cc
* @date 2021/5/21 11:14
* @param response
*/
@RequestMapping(value = "export")
public void export(HttpServletResponse response){
excelService.export(response);
}
}
5、POI相关API
5.1:POI EXCEL文档结构类
HSSFWorkbook excel文档对象
HSSFSheet excel的sheet HSSFRow excel的行
HSSFCell excel的单元格 HSSFFont excel字体
HSSFName 名称 HSSFDataFormat 日期格式
HSSFHeader sheet头
HSSFFooter sheet尾
HSSFCellStyle cell样式
HSSFDateUtil 日期
HSSFPrintSetup 打印
HSSFErrorConstants 错误信息表
5.2、导入Excel常用的方法:
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream("d:/test.xls"));
HSSFWorkbook wb = new HSSFWorkbook(fs); //得到Excel工作簿对象
HSSFSheet sheet = wb.getSheetAt(0); //得到Excel工作表对象
HSSFRow row = sheet.getRow(i); //得到Excel工作表的行
HSSFCell cell = row.getCell((short) j); //得到Excel工作表指定行的单元格
cellStyle = cell.getCellStyle(); //得到单元格样式
5.3、导出Excel常用的方法:
HSSFWorkbook wb = new HSSFWorkbook(); //创建Excel工作簿对象
HSSFSheet sheet = wb.createSheet("new sheet"); //创建Excel工作表对象
HSSFRow row = sheet.createRow((short)0); //创建Excel工作表的行
cellStyle = wb.createCellStyle(); //创建单元格样式
row.createCell((short)0).setCellStyle(cellStyle); //创建Excel工作表指定行的单元格
row.createCell((short)0).setCellValue(1); //设置Excel工作表的值
5.4、poi简介
1、设置sheet名称和单元格内容
workbook.setSheetName(1, "工作表",HSSFCell.ENCODING_UTF_16);
cell.setEncoding((short) 1);
cell.setCellValue("单元格内容"); 2、取得sheet的数目
workbook.getNumberOfSheets() 3、根据index取得sheet对象
HSSFSheet sheet = wb.getSheetAt(0); 4、取得有效的行数
int rowcount = sheet.getLastRowNum(); 5、取得一行的有效单元格个数
row.getLastCellNum(); 6、单元格值类型读写
cell.setCellType(HSSFCell.CELL_TYPE_STRING); //设置单元格为STRING类型
cell.getNumericCellValue();//读取为数值类型的单元格内容 7、设置列宽、行高
sheet.setColumnWidth((short)column,(short)width);
row.setHeight((short)height); 8、添加区域,合并单元格
// 合并从第rowFrom行columnFrom列
Region region = new Region((short)rowFrom,(short)columnFrom,(short)rowTo(short)columnTo);
// 到rowTo行columnTo的区域
sheet.addMergedRegion(region);
// 得到所有区域
sheet.getNumMergedRegions() 9、保存Excel文件
FileOutputStream fileOut = new FileOutputStream(path);
wb.write(fileOut); 10、根据单元格不同属性返回字符串数值
public String getCellStringValue(HSSFCell cell) {
String cellValue = "";
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_STRING://字符串类型
cellValue = cell.getStringCellValue();
if(cellValue.trim().equals("")||cellValue.trim().length()<=0)
cellValue=" ";
break;
case HSSFCell.CELL_TYPE_NUMERIC: //数值类型
cellValue = String.valueOf(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_FORMULA: //公式
cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
cellValue = String.valueOf(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_BLANK:
cellValue=" ";
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
break;
case HSSFCell.CELL_TYPE_ERROR:
break;
default:
break;
}
return cellValue;
} 11、常用单元格边框格式
HSSFCellStyle style = wb.createCellStyle();
style.setBorderBottom(HSSFCellStyle.BORDER_DOTTED);//下边框
style.setBorderLeft(HSSFCellStyle.BORDER_DOTTED);//左边框
style.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框
style.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框 12、设置字体和内容位置
HSSFFont f = wb.createFont();
f.setFontHeightInPoints((short) 11);//字号
f.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);//加粗
style.setFont(f);
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//左右居中
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//上下居中
style.setRotation(short rotation);//单元格内容的旋转的角度
HSSFDataFormat df = wb.createDataFormat();
style1.setDataFormat(df.getFormat("0.00%"));//设置单元格数据格式
cell.setCellFormula(string);//给单元格设公式
style.setRotation(short rotation);//单元格内容的旋转的角度 13、插入图片
//先把读进来的图片放到一个ByteArrayOutputStream中,以便产生ByteArray
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
BufferedImage bufferImg = ImageIO.read(new File("ok.jpg"));
ImageIO.write(bufferImg,"jpg",byteArrayOut);
//读进一个excel模版
FileInputStream fos = new FileInputStream(filePathName+"/stencil.xlt");
fs = new POIFSFileSystem(fos);
//创建一个工作薄
HSSFWorkbook wb = new HSSFWorkbook(fs);
HSSFSheet sheet = wb.getSheetAt(0);
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
HSSFClientAnchor anchor = new HSSFClientAnchor(0,0,1023,255,(short) 0,0,(short)10,10);
patriarch.createPicture(anchor , wb.addPicture(byteArrayOut.toByteArray(),HSSFWorkbook.PICTURE_TYPE_JPEG));14、调整工作表位置
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("format sheet");
HSSFPrintSetup ps = sheet.getPrintSetup();
sheet.setAutobreaks(true);
ps.setFitHeight((short)1);
ps.setFitWidth((short)1); 15、设置打印区域
HSSFSheet sheet = wordbook.createSheet("Sheet1");
wordbook.setPrintArea(0, "$A$1:$C$2"); 16、标注脚注
HSSFSheet sheet = wordbook.createSheet("format sheet");
HSSFFooter footer = sheet.getFooter()
footer.setRight( "Page " + HSSFFooter.page() + " of " + HSSFFooter.numPages() ); 17、在工作单中清空行数据,调整行位置
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("row sheet");
// Create various cells and rows for spreadsheet.
// Shift rows 6 - 11 on the spreadsheet to the top (rows 0 - 5)
sheet.shiftRows(5, 10, -5); 18、选中指定的工作表
HSSFSheet sheet = wb.createSheet("row sheet");
heet.setSelected(true); 19、工作表的放大缩小
HSSFSheet sheet1 = wb.createSheet("new sheet");
sheet1.setZoom(1,2); // 50 percent magnification 20、头注和脚注
HSSFSheet sheet = wb.createSheet("new sheet");
HSSFHeader header = sheet.getHeader();
header.setCenter("Center Header");
header.setLeft("Left Header");
header.setRight(HSSFHeader.font("Stencil-Normal", "Italic") +
HSSFHeader.fontSize((short) 16) + "Right w/ Stencil-Normal Italic font and size 16"); 21、自定义颜色
HSSFCellStyle style = wb.createCellStyle();
style.setFillForegroundColor(HSSFColor.LIME.index);
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
HSSFFont font = wb.createFont();
font.setColor(HSSFColor.RED.index);
style.setFont(font);
cell.setCellStyle(style); 22、填充和颜色设置
HSSFCellStyle style = wb.createCellStyle();
style.setFillBackgroundColor(HSSFColor.AQUA.index);
style.setFillPattern(HSSFCellStyle.BIG_SPOTS);
HSSFCell cell = row.createCell((short) 1);
cell.setCellValue("X");
style = wb.createCellStyle();
style.setFillForegroundColor(HSSFColor.ORANGE.index);
style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
cell.setCellStyle(style);23、强行刷新单元格公式
HSSFFormulaEvaluator eval=new HSSFFormulaEvaluator((HSSFWorkbook) wb);
private static void updateFormula(Workbook wb,Sheet s,int row){
Row r=s.getRow(row);
Cell c=null;
FormulaEcaluator eval=null;
if(wb instanceof HSSFWorkbook)
eval=new HSSFFormulaEvaluator((HSSFWorkbook) wb);
else if(wb instanceof XSSFWorkbook)
eval=new XSSFFormulaEvaluator((XSSFWorkbook) wb);
for(int i=r.getFirstCellNum();i
c=r.getCell(i);
if(c.getCellType()==Cell.CELL_TYPE_FORMULA)
eval.evaluateFormulaCell(c);
}
} 24、设置不显示excel网格线
sheet.setDisplayGridlines(false);//其中sheet是Sheet对象 25、设置excel单元格中的内容换行
cellStyle.setWrapText(true);
注意:其中cellStyle是WorkBook创建的CellStyle对象,然后将cellStyle设置到要换行的Cell对象,最后在要换行的对象(一般为字符串)加入"/r/n"。例如:
topTile.append("/r/n" +"cellContent"); 26、单元格的合并
sheet.addMergedRegion(new CellRangeAddress(0, 4, 0, 2));// 本示例为合并4行2列 27、设置页眉和页脚的页数
HSSFHeader header = sheet.getHeader();
header.setCenter("Center Header");
header.setLeft("Left Header");
header.setRight(HSSFHeader.font("Stencil-Normal", "Italic") +
HSSFHeader.fontSize((short) 16) + "Right w/ Stencil-Normal Italic font and size 16");
HSSFFooter footer = (HSSFFooter )sheet.getFooter()
footer.setRight( "Page " + HSSFFooter.page() + " of " + HSSFFooter.numPages() );28、使得一个Sheet适合一页
sheet.setAutobreaks(true); 29、设置放大属性(Zoom被明确为一个分数,例如下面的75%使用3作为分子,4作为分母)
sheet.setZoom(3,4); 30、设置打印
HSSFPrintSetup print = (HSSFPrintSetup) sheet.getPrintSetup();
print.setLandscape(true);//设置横向打印
print.setScale((short) 70);//设置打印缩放70%
print.setPaperSize(HSSFPrintSetup.A4_PAPERSIZE);//设置为A4纸张
print.setLeftToRight(true);//設置打印顺序先行后列,默认为先列行
print.setFitHeight((short) 10);设置缩放调整为10页高
print.setFitWidth((short) 10);设置缩放调整为宽高
sheet.setAutobreaks(false);
if (i != 0 && i % 30 == 0) {
sheet.setRowBreak(i);//設置每30行分頁打印
}31、反复的行和列(设置打印标题)
HSSFWorkbook wb = new HSSFWorkbook();
wb.setRepeatingRowsAndColumns(0, 0, 12, 1, 6);//设置1到12列,行1到6每一页重复打印 32、调整单元格宽度
sheet.setAutobreaks(true);
sheet.setColumnWidth((short)i,colsWidth[i]); //设定单元格长度
sheet.autoSizeColumn((short) i);//自动根据长度调整单元格长度