SpringBoot整合poi實現Excel的 匯入/匯出
阿新 • • 發佈:2018-12-13
- 新增依賴
<!-- excel匯出工具 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>com.monitorjbl</groupId> <artifactId>xlsx-streamer</artifactId> <version>1.2.0</version> </dependency>
- 建立一個返回檔案二進位制流的VO物件(如果不需要返回檔案二進位制流給前端,就無須建立)
package org.sc.api.ps.model.vo; import java.io.Serializable; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data public class ExportDataVo implements Serializable{ /** * */ private static final long serialVersionUID = 1L; /** 檔名稱 **/ @ApiModelProperty(value = "檔名稱") private String fileName; /** 檔案二進位制流 **/ @ApiModelProperty(value = "檔案二進位制流") private byte[] fileByte; }
- 引入WorkbookContext檔案(如果不需要返回檔案二進位制流給前端,就無須引入)
package org.sc.common.utils.poi.api.wookbook; import org.apache.poi.ss.usermodel.Workbook; import org.sc.common.utils.poi.api.configuration.ConfigurationProvider; import org.sc.common.utils.poi.api.sheet.SheetContext; import org.sc.common.utils.poi.api.style.StyleConfigurable; import org.sc.common.utils.poi.api.style.StyleConfiguration; import org.sc.common.utils.poi.api.style.StyleRegistry; import org.apache.poi.ss.usermodel.CellStyle; /** * Workbook context. * * @author i.voshkulat * */ public interface WorkbookContext extends ConfigurationProvider, StyleRegistry, StyleConfiguration, StyleConfigurable<WorkbookContext> { /** * Create new sheet within the current workbook. * * @param sheetName sheet name * @return created {@link SheetContext} */ public SheetContext createSheet(String sheetName); /** * Use an existing sheet within the current workbook * * @param sheetName sheet to use * @return existing {@link SheetContext} * @throws java.lang.IllegalArgumentException if a sheet with the given name doesn't exist */ public SheetContext useSheet(String sheetName); /** * Retrieve POI workbook referred to by current {@link WorkbookContext}. * Please refrain from using the exposed {@link Workbook} directly unless you need functionality of POI not provided by {@link WorkbookContext}. * To retrieve a workbook for saving to a file look at {@link #toNativeBytes()} instead. * * @return native POI {@link Workbook} */ public Workbook toNativeWorkbook(); /** * Create .xls file binary representation for current {@link WorkbookContext} * * @return excel file binary representation */ public byte[] toNativeBytes(); /** * xls and xlsx files have different default fonts * * @return font name */ public String getDefaultFontName(); public CellStyle createLeftStyleCell(WorkbookContext workbookCtx,boolean wrapText); public CellStyle createCenterStyleCell(WorkbookContext workbookCtx,boolean wrapText); public CellStyle createRedStyleCell(WorkbookContext workbookCtx,boolean wrapText); public CellStyle createTopStyleCell(WorkbookContext workbookCtx,boolean wrapText); public CellStyle createRightStyleCell(WorkbookContext workbookCtx,boolean wrapText); }
- 介面類
package org.sc.api.ps.service;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.sc.api.ps.model.vo.ExportDataVo;
import org.sc.common.model.vo.Response;
import org.springframework.web.multipart.MultipartFile;
public interface ExcelService {
/**
* 以Excel模板表匯入角色資訊
*
* @throws InvalidFormatException
* @throws EncryptedDocumentException
* @throws Exception
*/
Response importRole(MultipartFile file) throws EncryptedDocumentException, InvalidFormatException, Exception;
/**
* 匯出角色資訊列表
*
* @return
* @throws IOException
*/
String export() throws IOException;
/**
* 匯出角色資訊列表(返回檔案二進位制流)
*
* @return
*/
ExportDataVo exportFileStreams();
}
- 實現類
package org.sc.api.ps.service.impl;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Calendar;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.sc.api.ps.model.vo.ExportDataVo;
import org.sc.api.ps.service.ExcelService;
import org.sc.common.model.vo.Response;
import org.sc.common.utils.GetDate;
import org.sc.common.utils.poi.api.row.RowContext;
import org.sc.common.utils.poi.api.sheet.SheetContext;
import org.sc.common.utils.poi.api.wookbook.WorkbookContext;
import org.sc.common.utils.poi.impl.wookbook.WorkbookContextFactory;
import org.sc.common.utils.web.ResponseUtil;
import org.sc.facade.ps.model.table.Role;
import org.sc.facade.ps.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.monitorjbl.xlsx.StreamingReader;
@Service
public class ExcelServiceImpl implements ExcelService {
@Autowired
private RoleService roleService;
@Override
public Response importRole(MultipartFile file) throws Exception {
try {
// 流式的讀取 xlsx 檔案,將一些特別大的檔案拆分成小的檔案去讀。
Workbook workbook = StreamingReader.builder().rowCacheSize(1000)
.bufferSize(4096).open(file.getInputStream());
String value = "";
int i = 0;
for (Sheet sheet : workbook) {
Role answer = null;
for (Row r : sheet) {
if (i == 0) {// 遍歷每一行,注意:第 0 行為標題
i = 1;
continue;
}
int ceIndex = 0;
answer = new Role();
for (Cell cell : r) {
if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
value = cell.getStringCellValue();
} else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
if (file.getOriginalFilename().endsWith(".xls")) {
DataFormatter formatter = new DataFormatter();
value = formatter.formatCellValue(cell);
} else {
value = cell.getStringCellValue();
}
}
switch (ceIndex) {
case 0:
answer.setRoleName(value);// 角色名
break;
case 1:
answer.setRoleCode(value);// 角色編號
break;
case 2:
answer.setParentId(value);// 父級id
break;
}
ceIndex++;
}
roleService.addRole(answer);// 新增角色
}
}
} catch (IOException e) {
return ResponseUtil.error(e.getMessage());
}
return ResponseUtil.ok();
}
@Override
public String export() throws IOException {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("角色列表");
//合併單元格
sheet.addMergedRegion(new CellRangeAddress(0, 2, 0, 5));
//設定第一列單元格寬度
sheet.setColumnWidth(0,100*100);
//設定第二列單元格寬度
sheet.setColumnWidth(1,100*100);
//建立第一行
HSSFRow row0 = sheet.createRow(0);
//建立第二行
HSSFRow row1 = sheet.createRow(1);
//設定第一行單元格高度
row0.setHeight((short) 400);
//建立第一行第一列單元格
HSSFCell cell0_1 = row0.createCell(0);
//建立第二行第一列單元格
HSSFCell cell0_2 = row1.createCell(0);
//設定單元格的值
cell0_1.setCellValue("角色列表");
//改變字型樣式,步驟
HSSFFont hssfFont = wb.createFont();
//設定字型,紅色
hssfFont.setColor(HSSFFont.COLOR_RED);
//字型粗體顯示
hssfFont.setBold(true);
hssfFont.setFontName("宋體");
// 字型大小
hssfFont.setFontHeightInPoints((short) 22);
//設定樣式
HSSFCellStyle cellStyle = wb.createCellStyle();
cellStyle.setFont(hssfFont);
//設定單元格背景色
cellStyle.setFillForegroundColor(IndexedColors.GREY_40_PERCENT.getIndex());
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
//設定居中
cellStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
//設定邊框
cellStyle.setBorderBottom(BorderStyle.THIN); //下邊框
cellStyle.setBorderLeft(BorderStyle.DASH_DOT_DOT);//左邊框
cellStyle.setBorderTop(BorderStyle.THIN);//上邊框
cellStyle.setBorderRight(BorderStyle.THIN);//右邊框
//3.單元格使用樣式,設定第一行第一列單元格樣式
cell0_1.setCellStyle(cellStyle);
cell0_2.setCellStyle(cellStyle);
//建立表頭
setTitle(wb, sheet);
List<Role> roles = roleService.getRoles("");
//新增資料行,並且設定單元格資料
int rowNum = 4;
for (Role role:roles) {
HSSFRow row = sheet.createRow(rowNum);
row.createCell(0).setCellValue(role.getRoleName());
row.createCell(1).setCellValue(role.getRoleCode());
row.createCell(2).setCellValue(role.getParentId());
rowNum++;
}
//生成excel檔案
FileOutputStream fileOut = new FileOutputStream("e:\\"+System.currentTimeMillis()+".xls");
wb.write(fileOut);
fileOut.close();
return "1";
}
/***
* 設定表頭
*
* @param workbook
* @param sheet
*/
private void setTitle(HSSFWorkbook workbook, HSSFSheet sheet) {
HSSFRow row = sheet.createRow(3);
// 設定列寬,setColumnWidth的第二個引數要乘以256,這個引數的單位是1/256個字元寬度
sheet.setColumnWidth(0, 10 * 256);
sheet.setColumnWidth(1, 20 * 256);
sheet.setColumnWidth(2, 20 * 256);
// 設定為居中加粗
HSSFCellStyle style = workbook.createCellStyle();
HSSFFont font = workbook.createFont();
font.setBold(true);
style.setFont(font);
HSSFCell cell;
cell = row.createCell(0);
cell.setCellValue("角色名");
cell.setCellStyle(style);
cell = row.createCell(1);
cell.setCellValue("角色編號");
cell.setCellStyle(style);
cell = row.createCell(2);
cell.setCellValue("父級id");
cell.setCellStyle(style);
}
@Override
public ExportDataVo exportFileStreams() {
ExportDataVo vo=new ExportDataVo();
vo.setFileName(System.currentTimeMillis() + ".xls");
WorkbookContext workbookCtx = WorkbookContextFactory.createWorkbook(true);
CellStyle center = workbookCtx.toNativeWorkbook().createCellStyle();
center.setWrapText(true);
CellStyle left = workbookCtx.toNativeWorkbook().createCellStyle();
SheetContext sheetCtx = workbookCtx.createSheet("角色列表");
RowContext top = sheetCtx.nextRow().skipCell().setRowHeight(40);
top.text("角色名", center).setColumnWidth(10);
top.text("角色編號", center).setColumnWidth(15);
top.text("父級id", center).setColumnWidth(15);
List<Role> roles = roleService.getRoles("");
for(int i=0;i<roles.size();i++){
Role role = roles.get(i);
RowContext tempSkipCell = sheetCtx.nextRow().skipCell().setRowHeight(25);
tempSkipCell.text(role.getRoleName(),center);
tempSkipCell.text(role.getRoleCode(),center);
tempSkipCell.text(role.getParentId(),center);
}
vo.setFileByte(workbookCtx.toNativeBytes());
return vo;
}
}
- 控制類
package org.sc.api.ps.controller;
import javax.servlet.http.HttpServletResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.sc.api.ps.model.vo.ExportDataVo;
import org.sc.api.ps.service.ExcelService;
import org.sc.common.controller.BaseController;
import org.sc.common.model.vo.Response;
import org.sc.common.utils.web.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
/**
* spring boot整合poi實現Excel的匯入匯出
*
* @author lv
*/
@Api(value = "excel",description = "Excel匯入匯出")
@RestController
@RequestMapping(value = "/api/ps/excel")
public class ExcelController extends BaseController {
@Autowired
private ExcelService excelService;
@ApiOperation(value = "以Excel模板表匯入角色資訊")
@RequestMapping(value="/importRole",method = RequestMethod.POST)
public Response importRole(@RequestBody MultipartFile file) throws Exception {
if (file==null) {
return ResponseUtil.error("file不能為空");
}
return excelService.importRole(file);
}
@ApiOperation(value = "匯出角色資訊列表")
@RequestMapping(value="/export",method = RequestMethod.GET)
public Response export() throws Exception {
return ResponseUtil.ok(excelService.export());
}
@ApiOperation(value = "匯出角色資訊列表(返回檔案二進位制流)")
@RequestMapping(value="/exportFileStreams",method = RequestMethod.GET)
public ResponseEntity<byte[]> exportFileStreams() throws Exception {
ExportDataVo vo = excelService.exportFileStreams();
HttpHeaders headers = new HttpHeaders();
String fileName = new String(vo.getFileName().getBytes("UTF-8"), "iso-8859-1");
headers.setContentDispositionFormData("attachment", fileName);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<>(vo.getFileByte(), headers,HttpStatus.CREATED);
}
}
結尾…