导出excel功能:
//首先把要导出文件的模板放到项目默认的地址下,(也就是webapp地址下)
Controller
@RequestMapping("value="")
//导出方法
public String getExportExcel(HttpServletRequest request, HttpSeiions session,
HttpServletResponse response,//包括前台传过来的参数(自己定义) ){
log.info("--------------正在导出文件");
//获取模板的位置,以及要导出的路径
//模板的位置
String modelPath = session.getServletContext().getRealPath("/")+"模板的位置.xlsx";
//导出的路径地址
String hisPath = session.getServletContext().getRealPath("/")+"导出的路径";
//相当于模板对象
Workbook book;
try{
//获取模板文件
File excelFile = new File(modelPath);
book = WorkbookFactory.creat(excelFile);
//获取你要导出的信息,将其封装为list对象(就是业务逻辑处理的结果集)
//List<封装的实体类> list = 你的service层.service方法(前台传的参数);
如:List<AmReportFormSalePriceSection> amReportingList = amReportingService.getSalePriceSectionList(propertyLevel, priceSection, wslName);
//你的service层.导出的方法(book, list, hisPath);
如:amReportingService.getReportFormSalePriceSectionExcel(book, amReportingList, hisPath);
//如果你要导出的excel是多个sheet组成的,并且在导出后只显示当前的某一个sheet,
//其他sheet都默认删除,则执行下面的遍历删除,如果不需要则不用执行
/**
* for(sheet的数量遍历){
* if(当不是当前显示的sheet则进行删除){
* book.removeSheetAt(遍历序号);
* }
*/
//设置导出格式
response.setCharacterEncoding("utg-8");
//设置文件ContentType类型,这样设置会自动判断下载文件类型
response.setContentType("multipart/form-data");
//设置文件头;最后一个参数是设置下载文件名
response.setHeader("Content-Disposition", "attachment;fileName="+new String("导出文件的名称".getBytes("UTF-8"),"ISO-8859-1")+".xlsx");
response.setHeader("Pragma","No-cache");
OutputStream out = response.getOutputStream();
book.write(out);
out.flush();
out.close();
}catch(Exception e){
log.error("发生异常 msg={}","原因:",e);
return 导出失败信息;
}
return 导出成功信息;
}
Service实现类:
@Override
public void getExportExcel(Workbook book, List<AmReportFormSalePriceSection> amReportingList,
String hisPath){
try{
//获取要导出的excel模板中的该sheet(也就是当前要导出的sheet的下标(一般都以零为第一个))
Sheet sheetArea = book.getSheetAt(6); //假设现在要导出的sheet是在模板中的第七个
int rowNum = 10; //在要导出的sheet中,导出数据是从该sheet中的第几行开始数据导出的(起始下标也是从零开始)
Row dkCopyRow = sheetArea.getRow(10);
//开始遍历导出的数据,进行数据导出
while(amReportingList != null && amReportingList.size() > 0){
//由于导出数据过多,则进行分页导出,每页2000条内,所以要设置一个临时集合存放当前导出的数据(每一页)
List<AmReportFormSalePriceSection> subList = amReportingList.subList(0,Math.min(2000,amReportingList.size()));
for(AmReportFormSalePriceSection reportForm : subList){
Row trow = sheetArea.getRow(rowNum);
if(trow == null){
trow = sheetArea.createRow(rowNum);
ExcelUtil.copyRow(book, dkCopyRow, trow);
}
//service实现类中的方法(实现单挑要导出的数据填入excel中的一行)
seRowValueOfSheet(reportForm, trow, 10);
rowNum++;
}
//进行释放该集合
subList.clear(Exception e);
}
}catch(Exception e){
log.error("发生异常 msg={}", "原因:", e);
throw new RuntimeException(e);
}
}
//service实现类中的方法(实现单条要导出的数据填入excel中的一行)
public void seRowValueOfSheet(Object o, Row row, int sheetNum){
//getDeclareFields()方法返回该类中所有的字段包括共有的和私有的
//getFieds()方法是返回该类对应的公共类字段
List<Field> list = Arrays.asList(o.getClass().getDeclareFields());
for(int i = 0; i < list.size(); i++){
Field field = list.get(i);
if(field.isAnnotationPresent(ImportSign.class)){
//ImportSign是单独建立的一个有关导出注解的类具体在下面(@注释)
ImportSign importSign = field.getAnnotation(ImportSign.class);
int cellNum = importSign.cellNum();
if(cellNum == -1){
continue;
}
Cell cell = row.getCell(cellNum);
if(cell == null){
cell = row.createCell(cellNum);
CellStyle cellStyle = cell.getCellStyle();
cellStyle.setClocked(false);
cellStyle.setBorderTop(BorderStyle.THIN);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
}
//获取该字段的数据类型
String fieldTypeName = field.getType().getName();
try{
//获取该字段的编码
String fileName = field.getName();
//通过该字段来获取该字段的get方法
Method method = o.getClass().getMethod(
"get" + fileName.subString(0,1).toUpperCase() + fileName.subString(1));
//执行该字段的get方法,获取该字段的值
Object v = method.invoke(o);
if (null != v) {
if (fieldTypeName.) {
cell.setCellValue(v.toString());
}else if (fieldTypeName.contains("BigDecimal")) {
BigDecimal b = new BigDecimal(v.toString());
cell.setCellValue(b.doubleValue());
} else if (fieldTypeName.contains("Date")) {
SimpleDateFormat sd = new SimpleDateFormat("yyyy/MM/dd");
cell.setCellValue(sd.format(new Date(v.toString())));
}
}
}catch(Exception e){
log.error("发生异常 msg={}", "原因:", e);
}
}
}
}
ExcelUtil类
public class ExcelUtil [
/**
*行复制功能
*/
public static void copyRow(Workbook wb, Row fromRow, Row toRow) {
toRow.setHeight(fromRow.getHeight());
CellStyle newStyle = wb.createCellStyle();
for(Iterator<Cell> cellTt = fromRow.cellIterator(); cellTt.hasNext();) {
Cell tmpCell = (Cell) cellTr.next();
Cell newCell = toRow.createCell(tmpCell.getColumnIndex());
copyCell(wb, newStyle, tmpCell, newCell);
}
Sheet worksheet = fromRow.getSheet();
for(int i = 0; i < worksheet.getNumMergedRegions(); i++) {
CellRangeAddress cellRangeAndress = worksheet.getMergedRegion(i);
if(cellRangeAddress.getFirstRow() == fromRow.getRowNum()) {
CellRangeAddress newCellRangeAddress = new CellRangeAddress(toRow.getRowNum(), (toRow.getRowNum() +
(cellRangeAddress.getLastRow() - cellRangeAddress.getFirstRow())), cellRangeAddress
.getFirstColumn(), cellRangeAddress.getLastColumn());
worksheet.addMergedRegionUnsafe(newCellRangeAddress);
}
}
}
/**
*复制单元格
* @param srcCell
* @param distCell
* @param //copyValueFlag true则连同cell的内容一起复制
*/
public static void copyCell(Workbook wb,CellStyle newStyle, Cell srcCell, Cell distCell) {
CellStyle srcStyle = srcCell.getCellStyle();
newStyle.cloneStyleFrom(srcStyle);
newStyle.setFont(wb.getFontAt(srcStyle.getFontIndex()));
newStyle.setLocked(false);
newStyle.setBorderTop(BorderStyle.THIN);
newStyle.setBorderBottom(BorderStyle.THIN);
newStyle.setBorderLeft(BorderStyle.THIN);
newStyle.setBorderRight(BorderStyle.THIN);
//样式
distCell.setCellStyle(newStyle);
//评论
if(srcCell.getCellComment() != null) {
distCell.setCellComment(srcCell.getCellComment());
}
// 不同数据类型处理
CellType srcCellType = srcCell.getCellTypeEnum();
distCell.setCellType(srcCellType);
if(srcCellType == CellType.NUMERIC) {
if(org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(srcCell)) {
distCell.setCellValue(srcCell.getDateCellValue());
} else {
distCell.setCellValue(srcCell.getNumericCellValue());
}
} else if(srcCellType == CellType.STRING) {
distCell.setCellValue(srcCell.getRichStringCellValue());
} else if(srcCellType == CellType.BLANK) { } else if(srcCellType == CellType.BOOLEAN) {
distCell.setCellValue(srcCell.getBooleanCellValue());
} else if(srcCellType == CellType.ERROR) {
distCell.setCellErrorValue(srcCell.getErrorCellValue());
} else if(srcCellType == CellType.FORMULA) {
distCell.setCellFormula(srcCell.getCellFormula());
} else {
}
}
}
@注释:
@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ImportSign {
int cellNum() default -1;//excel 列序号
boolean isnull() default false;//是否可以为空,默认不可以为空
boolean isYn() default false;//单元格是否为是/否值,如果等于true时自动将是转换成1,否转换成0
boolean isDict() default false;//单元格是否为数据字典值,如果等于true时,则需要转换
int columnLength() default 0; //单元格值字节长度
String dictGroupCode() default "";//当isDict为true时,设置对应的字典组编码
String description() default "";//描述
}
在实现导出功能的时候,我们使用字段加注解的方式)
在实体类中需要进行导出的字段上加注解
如:
@ImportSign(cellNum = 1, isnull = true, description = "区域名称", columnLength = 50)
private String areaName;