SpringBoot整合POI導(dǎo)出通用Excel的方法示例
一、準(zhǔn)備工作
1、pom依賴
在pom.xml中加入POI的依賴
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.11-beta1</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>3.11-beta1</version> </dependency>
2、自定義注解
自定義注解,用于定義excel單元格的相關(guān)信息,用在需要導(dǎo)出的類上。
大家可以根據(jù)自己的實(shí)際需求來定義更多的內(nèi)容。
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelResources {
int order() default 9999;//定義字段在excel的單元格列坐標(biāo)位置
String title() default "";//定義列坐標(biāo)對(duì)應(yīng)的標(biāo)題
int cloumn() default 100;//定義列寬
String pattern() default "";//定義日期顯示格式
}
3、定義需要導(dǎo)出的實(shí)體
舉例說明@ExcelResources 的應(yīng)用場(chǎng)景,我們創(chuàng)建一個(gè)demoModel,包含姓名、年齡、性別、日期。
后邊的excel導(dǎo)出例子也采用這個(gè)實(shí)體類來舉例。
@Data
public class ExcelDemoModel {
@ExcelResources(order=0,title = "姓名",cloumn = 10)
private String name;
@ExcelResources(order=1,title = "年齡",cloumn = 10)
private Integer age;
@ExcelResources(order=2,title = "創(chuàng)建時(shí)間",cloumn = 24,pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@ExcelResources(order=3,title = "性別",cloumn = 10)
private SexType sex;//枚舉
}
4、定義導(dǎo)出輔助類
用于存放導(dǎo)出的excel對(duì)應(yīng)標(biāo)題和列寬
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TitleAndCloumn {
private String title;//標(biāo)題
private int cloumn;//列寬
}
二、具體的導(dǎo)出方法
1、導(dǎo)出主要方法
@Service
public class ExcelService {
private static float title_row_height=30;//標(biāo)題行高
private static float data_row_height=25;//數(shù)據(jù)行高
public void exportExcel(HttpServletRequest request, HttpServletResponse response, String fileName ,List<?> excelDatas,Class<?> clz ) {
try {
HSSFWorkbook resultWb=new HSSFWorkbook();
HSSFSheet sheet=resultWb.createSheet();//創(chuàng)建sheet
//根據(jù)類類型信息獲取導(dǎo)出的excel對(duì)應(yīng)的標(biāo)題和列寬 key-列號(hào),value-標(biāo)題和列寬
HashMap<Integer, TitleAndCloumn> orderTitleAndCloumnMap=getTitleAndCloumnMap(clz);
//設(shè)置列寬
orderTitleAndCloumnMap.forEach((k,v) -> {
sheet.setColumnWidth(k, v.getCloumn()*256);
});
HSSFRow row0=sheet.createRow(0);
//設(shè)置標(biāo)題行高
row0.setHeightInPoints(title_row_height);
//創(chuàng)建標(biāo)題單元格格式
HSSFCellStyle titleCellStyle=getCellStyle(resultWb,11,true,HSSFColor.BLACK.index);
//填充標(biāo)題行內(nèi)容
orderTitleAndCloumnMap.forEach((k,v) -> {
HSSFCell row0Cell=row0.createCell(k);
row0Cell.setCellValue(v.getTitle());
row0Cell.setCellStyle(titleCellStyle);
});
//創(chuàng)建正文單元格格式
HSSFCellStyle dataStyle = getCellStyle(resultWb,11,false,HSSFColor.BLACK.index);
//將正文轉(zhuǎn)換為excel數(shù)據(jù)
int rowNum=1;
for(Object data:excelDatas){
HSSFRow row=sheet.createRow(rowNum++);
row.setHeightInPoints(data_row_height);
//獲取對(duì)象值 key-列號(hào) value-String值
HashMap<Integer,String> orderValueMap=getValueMap(data);
orderValueMap.forEach((k,v) ->{
HSSFCell cell=row.createCell(k);
cell.setCellValue(v);
cell.setCellStyle(dataStyle);
}
);
}
String downFileName=fileName+".xls";
response.setContentType("application/vnd.ms-excel; charset=UTF-8");// application/x-download
response.setHeader("Content-Disposition", "attachment; "
+encodeFileName(request, downFileName));
OutputStream outputStream = response.getOutputStream();
resultWb.write(outputStream);
outputStream.flush();
outputStream.close();
resultWb.close();
}catch (Exception e1) {
e1.printStackTrace();
}
}
}
2、通過反射獲取excel標(biāo)題和列寬
/**
* 獲取類的屬性對(duì)應(yīng)單元格標(biāo)題和列寬
* @param
* @return
*/
private static HashMap<Integer, TitleAndCloumn> getTitleAndCloumnMap(Class<?> clz) {
HashMap<Integer, TitleAndCloumn> orderTitleAndCloumnMap=new HashMap<>();
Field[] fs = clz.getDeclaredFields();
for(Field f:fs) {
f.setAccessible(true);
if(f.isAnnotationPresent(ExcelResources.class)) {
Integer order=f.getAnnotation(ExcelResources.class).order();
String title=f.getAnnotation(ExcelResources.class).title();
int cloumn=f.getAnnotation(ExcelResources.class).cloumn();
TitleAndCloumn titleAndCloumn=new TitleAndCloumn(title,cloumn);
orderTitleAndCloumnMap.put(order,titleAndCloumn);
}
}
return orderTitleAndCloumnMap;
}
3、創(chuàng)建CellStyle
通過傳入?yún)?shù)定義簡單地CellStyle
public HSSFCellStyle getCellStyle(HSSFWorkbook workbook,int fontSize,boolean isBoleaWeight,short color){
HSSFCellStyle style = workbook.createCellStyle();
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//水平居中
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直居中
style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
style.setBorderRight(HSSFCellStyle.BORDER_THIN);
style.setBorderTop(HSSFCellStyle.BORDER_THIN);
HSSFFont font = workbook.createFont();
font.setFontHeightInPoints((short) fontSize);//字號(hào)
font.setColor(color);//顏色
font.setFontName("宋體");//字體
if(isBoleaWeight){
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); //字體加粗
}
style.setWrapText(true);
style.setFont(font);
return style;
}
4、通過反射獲取對(duì)象信息并處理成String字符串
我這里只涉及到基本數(shù)據(jù)類型和Date以及枚舉的值獲取和轉(zhuǎn)換,小伙伴可以根據(jù)自己的實(shí)際情況進(jìn)行修改。
/**
* 獲取對(duì)象的屬性對(duì)應(yīng)單元格坐標(biāo)和值的鍵值對(duì)
* @param obj
* @return
*/
private static HashMap<Integer, String> getValueMap(Object obj) throws IllegalAccessException {
HashMap<Integer, String> result=new HashMap<>();
Class<?> clz=obj.getClass();
Field[] fs = clz.getDeclaredFields();
for(Field f:fs) {
f.setAccessible(true);
if(f.isAnnotationPresent(ExcelResources.class)) {
Integer order=f.getAnnotation(ExcelResources.class).order();
String value="";
Object valueObj=f.get(obj);
if(valueObj!=null) {
//日期格式進(jìn)行特殊處理
if(f.getType()==Date.class){
String pattern=f.getAnnotation(ExcelResources.class).pattern();
if(StringUtils.isEmpty(pattern)){
pattern="yyyy-MM-dd HH:mm:ss";
}
SimpleDateFormat sdf=new SimpleDateFormat(pattern);
value=sdf.format(valueObj);
}else{
value=valueObj.toString();//其他格式調(diào)用toString方法,這里枚舉就需要定義自己的toString方法
}
}
result.put(order, value);
}
}
return result;
}
5、枚舉的定義
如果有用到枚舉存儲(chǔ)在數(shù)據(jù)庫的小伙伴,可以自定義枚舉的toString方法來實(shí)現(xiàn)excel導(dǎo)出時(shí)候相應(yīng)的內(nèi)容
public enum SexType {
male("男"),
female("女"),
;
private String typeName;
SexType(String typeName) {
this.typeName = typeName;
}
@Override
public String toString() {
return typeName;
}
}
6、encodeFileName
/**
* 根據(jù)不同的瀏覽器生成不同類型中文文件名編碼
*
* @param request
* @param fileName
* @return
* @throws UnsupportedEncodingException
*/
public static String encodeFileName(HttpServletRequest request, String fileName)
throws UnsupportedEncodingException
{
String new_filename = URLEncoder.encode(fileName, "UTF8").replaceAll("\\+", "%20");
String agent = request.getHeader("USER-AGENT").toLowerCase();
if (null != agent && -1 != agent.indexOf("msie"))
{
/**
* IE瀏覽器,只能采用URLEncoder編碼
*/
return "filename=\"" + new_filename +"\"";
}else if (null != agent && -1 != agent.indexOf("applewebkit")){
/**
* Chrome瀏覽器,只能采用ISO編碼的中文輸出
*/
return "filename=\"" + new String(fileName.getBytes("UTF-8"),"ISO8859-1") +"\"";
} else if (null != agent && -1 != agent.indexOf("opera")){
/**
* Opera瀏覽器只可以使用filename*的中文輸出
* RFC2231規(guī)定的標(biāo)準(zhǔn)
*/
return "filename*=" + new_filename ;
}else if (null != agent && -1 != agent.indexOf("safari")){
/**
* Safani瀏覽器,只能采用iso編碼的中文輸出
*/
return "filename=\"" + new String(fileName.getBytes("UTF-8"),"ISO8859-1") +"\"";
}else if (null != agent && -1 != agent.indexOf("firefox"))
{
/**
* Firfox瀏覽器,可以使用filename*的中文輸出
* RFC2231規(guī)定的標(biāo)準(zhǔn)
*/
return "filename*=" + new_filename ;
} else
{
return "filename=\"" + new_filename +"\"";
}
}
三、方法調(diào)用案例
1、方法調(diào)用
public void exportExcelDemo(HttpServletRequest request, HttpServletResponse response) {
//一系列查詢處理
List<ExcelDemoModel> demoList=new ArrayList<>();
excelService.exportExcel(request,response,"人員信息demo",demoList,ExcelDemoModel.class);
}
2、導(dǎo)出效果

到此這篇關(guān)于SpringBoot整合POI導(dǎo)出通用Excel的方法示例的文章就介紹到這了,更多相關(guān)SpringBoot整合POI導(dǎo)出Excel內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot集成POI實(shí)現(xiàn)Excel導(dǎo)入導(dǎo)出的示例詳解
- SpringBoot+EasyPoi實(shí)現(xiàn)excel導(dǎo)出功能
- 使用Springboot+poi上傳并處理百萬級(jí)數(shù)據(jù)EXCEL
- SpringBoot中使用JeecgBoot的Autopoi導(dǎo)出Excel的方法步驟
- Springboot POI導(dǎo)出Excel(瀏覽器)
- Springboot使用POI實(shí)現(xiàn)導(dǎo)出Excel文件示例
- SpringBoot整合POI實(shí)現(xiàn)Excel文件讀寫操作
相關(guān)文章
詳解如何將JAVA程序制作成可以直接執(zhí)行的exe文件
這篇文章主要介紹了詳解如何將JAVA程序制作成可以直接執(zhí)行的exe文件,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
淺談Java8 的foreach跳出循環(huán)break/return
這篇文章主要介紹了Java8 的foreach跳出循環(huán)break/return,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
IDEA導(dǎo)入外部項(xiàng)目報(bào)Error:java: 無效的目標(biāo)發(fā)行版: 11的解決方法
這篇文章主要介紹了IDEA導(dǎo)入外部項(xiàng)目報(bào)Error:java: 無效的目標(biāo)發(fā)行版: 11,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09
Java實(shí)現(xiàn)調(diào)用jython執(zhí)行python文件的方法
這篇文章主要介紹了Java實(shí)現(xiàn)調(diào)用jython執(zhí)行python文件的方法,結(jié)合實(shí)例形式分析了Java調(diào)用jython執(zhí)行python文件的常見操作技巧及相關(guān)問題解決方法,需要的朋友可以參考下2018-03-03
SpringBoot公共頁面抽取方法實(shí)現(xiàn)過程介紹
這篇文章主要介紹了SpringBoot抽取公共頁面的方法實(shí)現(xiàn)過程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-10-10
RocketMQ4.5.X 實(shí)現(xiàn)修改生產(chǎn)者消費(fèi)者日志保存路徑
這篇文章主要介紹了RocketMQ4.5.X 實(shí)現(xiàn)修改生產(chǎn)者消費(fèi)者日志保存路徑方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
Java迭代器實(shí)現(xiàn)Python中的range代碼實(shí)例
這篇文章主要介紹了Java迭代器實(shí)現(xiàn)Python中的range代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03

