需要源代碼的可以加我微信好友gqljxg1514
1,首先配置依賴pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.nn-kc</groupId> <artifactId>nnkc-reportexcel</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>nnkc-reportexcel Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.2</version> </dependency> <dependency> <groupId>org.mortbay.jetty</groupId> <artifactId>servlet-api-2.5</artifactId> <version>6.1.9</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.9</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.3</version> </dependency> </dependencies> <build> <finalName>nnkc-reportexcel</finalName> </build> </project>
2,創建實體類Product.java

package com.nnkc.pojo; import com.nnkc.util.ExcelAnnotation; import java.util.Date; public class Product { @ExcelAnnotation(id=1,name={"產品名稱","商品名稱"},width = 5000) private String name; @ExcelAnnotation(id=2,name={"產品價格","商品價格"},width = 5000) private double price; @ExcelAnnotation(id=3,name={"生產日期"},width = 5000) private Date date; public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } }
3,編寫工具類/nnkc-reportexcel/src/main/java/com/nnkc/util/ExcelAnnotation.java

package com.nnkc.util; import java.lang.annotation.*; /** * <p> * 功能:excel模板設置 * </p> */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface ExcelAnnotation { //Excel列ID(Excel列排序序號) int id(); //Excel列名 String[] name(); //Excel列寬 int width() default 5000; }
以及/nnkc-reportexcel/src/main/java/com/nnkc/util/ExcelUtil.java

package com.nnkc.util; import org.apache.poi.hssf.usermodel.*; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.hssf.util.Region; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFRichTextString; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.*; public class ExcelUtil<T> { public static final int EXPORT_07_LEAST_SIZE = 50000; public static final int EXPORT_07S_LEAST_SIZE = 100000; /** * 功能 :獲取表單導出數據 * @param list 數據列表 * @param title 首行標題 * @param className 實體對象class * @param exportType 模板標號 * @return * @throws Exception */ public HSSFWorkbook exportExcel(List<T> list, String title, Class className,Integer exportType) throws Exception { // 獲取屬性 Field[] fields = className.getDeclaredFields(); List<Field> fieldList = new ArrayList<Field>(); for (Field fie : fields) { if (fie.isAnnotationPresent(ExcelAnnotation.class)) { fieldList.add(fie); } } // 按照id進行排序 Collections.sort(fieldList, new Comparator<Field>() { public int compare(Field f1, Field f2) { return f1.getAnnotation(ExcelAnnotation.class).id() - f2.getAnnotation(ExcelAnnotation.class).id(); } }); int columnsize = fieldList.size(), rowindex = 0; // 創建一個HSSFWorbook對象(excel的文檔對象) HSSFWorkbook hWorkbook = new HSSFWorkbook(); // 創建一個HSSFSheet對象(excll的表單) HSSFSheet hSheet = hWorkbook.createSheet(); // 創建行(excel的行) HSSFRow hRow = hSheet.createRow(rowindex++); //設置行高度 hRow.setHeight((short)380); // 創建單元格(從0開始) HSSFCell hCell = hRow.createCell((short) 0); //樣式對象 HSSFCellStyle cellStyle = getCellStyle(hWorkbook, (short) 300, (short) 500); // 將上面獲得的樣式對象給對應單元格 hCell.setCellStyle(cellStyle); //設置標題行 hCell.setCellValue(title); if (getHuoResult(fieldList.isEmpty(),list == null,list.isEmpty())) { return hWorkbook; } //創建第二行,代表列名 hRow = hSheet.createRow(rowindex++); cellStyle = getCellStyle(hWorkbook, (short) 270, (short) 500); generateTitle(exportType, fieldList, columnsize, hSheet, hRow, cellStyle); //組裝excel的數據 cellStyle = getCellStyle(hWorkbook, (short) 220, (short) 500);// 設置單元格格式 generateData(list, fieldList, columnsize, rowindex, hSheet, cellStyle); /** * 第1個參數:從哪一行開始 * 第2個參數:到哪一行結束 * 第3個參數:從哪一列開始 * 第4個參數:到哪一列結束 */ hSheet.addMergedRegion(new CellRangeAddress(0,0,0,columnsize-1)); // 固定表頭(前一個參數代表列,后一個參數單表行) hSheet.createFreezePane(0, 1); return hWorkbook; } /** * 功能:組裝列明 * @param exportType 模板編號 * @param fieldList 列名 * @param columnsize 列數 * @param hSheet sheet頁 * @param hRow 行 * @param cellStyle 樣式 */ private void generateTitle(Integer exportType, List<Field> fieldList, int columnsize, HSSFSheet hSheet, HSSFRow hRow, HSSFCellStyle cellStyle) { HSSFCell hCell; for (int i = 0; i < columnsize; i++) { Field field = fieldList.get(i); if (field.isAnnotationPresent(ExcelAnnotation.class)) { // 獲取該字段的注解對象 ExcelAnnotation anno = field.getAnnotation(ExcelAnnotation.class); hCell = hRow.createCell((short) i); String colName = field.getAnnotation(ExcelAnnotation.class).name().length>exportType ?field.getAnnotation(ExcelAnnotation.class).name()[exportType] :field.getAnnotation(ExcelAnnotation.class).name()[0]; hCell.setCellValue(colName); hCell.setCellStyle(cellStyle); hSheet.setColumnWidth((short) i, (short) anno.width()); } } } /** * 組裝excel的數據 * @param list 具體數據 * @param fieldList 列名 * @param columnsize 列數 * @param rowindex 行數計數 * @param hSheet sheet頁 * @param cellStyle 樣式 * @return * @throws NoSuchMethodException * @throws IllegalAccessException * @throws InvocationTargetException */ private int generateData(List<T> list, List<Field> fieldList, int columnsize, int rowindex, HSSFSheet hSheet, HSSFCellStyle cellStyle) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { HSSFRow hRow; HSSFCell hCell; for (Object model : list) { hRow = hSheet.createRow(rowindex++); //獲取該類 Class clazz = model.getClass(); for (int i = 0; i < columnsize; i++) { Field field =fieldList.get(i); //獲取方法名 String methodName = "get" + field.getName().substring(0, 1).toUpperCase()+field.getName().substring(1); Method method = clazz.getMethod(methodName); try { // 獲取該字段的注解對象 Object result = method.invoke(model); hCell = hRow.createCell((short) i); if (result != null) { if (result.getClass().isAssignableFrom(Date.class)) { SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日"); result = format.format(result); } hCell.setCellValue(new HSSFRichTextString(result.toString())); } else { hCell.setCellValue(new HSSFRichTextString("-")); } hCell.setCellStyle(cellStyle); } catch (IllegalArgumentException e) { System.out.println(e.getMessage()); } } } return rowindex; } /** * 生成07格式的excel對象 使用流方式防止內存溢出 * @param list * @param title * @param className * @param exportType * @return * @throws Exception */ public SXSSFWorkbook exportExcel07S(List<T> list, String title, Class className,Integer exportType) throws Exception { // 獲取屬性 Field[] fields = className.getDeclaredFields(); List<Field> fieldList = new ArrayList<Field>(); for (Field fie : fields) { if (fie.isAnnotationPresent(ExcelAnnotation.class)){ fieldList.add(fie); } } // 按照id進行排序 Collections.sort(fieldList, new Comparator<Field>() { public int compare(Field f1, Field f2) { return f1.getAnnotation(ExcelAnnotation.class).id() - f2.getAnnotation(ExcelAnnotation.class).id(); } }); int columnsize = fieldList.size(), rowindex = 0; // 創建一個HSSFWorbook對象s SXSSFWorkbook hWorkbook = new SXSSFWorkbook(); // 創建一個HSSFSheet對象(sheet頁) Sheet hSheet = hWorkbook.createSheet(); // 創建第一行(此行作為頭) Row hRow = hSheet.createRow(rowindex++); hRow.setHeight((short)380); // 創建單元格(第一(0)個) Cell hCell = hRow.createCell((short) 0); // 設置樣式 CellStyle cellStyle = getCellStyle07S(hWorkbook, (short) 300, (short) 500); // 將上面獲得的樣式對象給對應單元格 hCell.setCellStyle(cellStyle); //設置標題行 hCell.setCellValue(title); if (getHuoResult(fieldList.isEmpty(),list == null,list.isEmpty())) { return hWorkbook; } // 創建第二列,列名 hRow = hSheet.createRow(rowindex++); cellStyle = getCellStyle07S(hWorkbook, (short) 270, (short) 500); createTitle07S(exportType, fieldList, columnsize, hSheet, hRow, cellStyle); //生成數據 cellStyle = getCellStyle07S(hWorkbook, (short) 220, (short) 500);// 設置單元格格式 dealCreateRow07S(list, fieldList, columnsize, rowindex, hSheet, cellStyle); /** * 第1個參數:從哪一行開始 * 第2個參數:到哪一行結束 * 第3個參數:從哪一列開始 * 第4個參數:到哪一列結束 */ hSheet.addMergedRegion(new CellRangeAddress(0,0,0,columnsize-1)); // 固定表頭(前一個參數代表列,后一個參數單表行) hSheet.createFreezePane(0, 1); return hWorkbook; } private int dealCreateRow07S(List<T> list, List<Field> fieldList, int columnsize, int rowindex, Sheet hSheet, CellStyle cellStyle) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { Row hRow; Cell hCell; for (Object model : list) { hRow = hSheet.createRow(rowindex++); // 獲取該類 並獲取自身方法 Class clazz = model.getClass(); for (int i = 0; i < columnsize; i++) { Field field = fieldList.get(i); String methodName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1); Method method = clazz.getMethod(methodName); try { // 獲取該字段的注解對象 Object result = method.invoke(model); hCell = hRow.createCell((short) i); if (result != null) { if (result.getClass().isAssignableFrom(Date.class)) { SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日"); result = format.format(result); } hCell.setCellValue(new XSSFRichTextString(result.toString())); } else { hCell.setCellValue(new XSSFRichTextString("-")); } hCell.setCellStyle(cellStyle); } catch (IllegalArgumentException e) { System.out.println(e.getMessage()); } } } return rowindex; } /** * 生成列名 * @param exportType 模板編號 * @param fieldList 列名 * @param columnsize 列數 * @param hSheet * @param hRow * @param cellStyle */ private void createTitle07S(Integer exportType, List<Field> fieldList, int columnsize, Sheet hSheet, Row hRow, CellStyle cellStyle) { Cell hCell; for (int i = 0; i < columnsize; i++) { Field field = (Field) fieldList.get(i); if (field.isAnnotationPresent(ExcelAnnotation.class)) { // 獲取該字段的注解對象 ExcelAnnotation anno = field.getAnnotation(ExcelAnnotation.class); hCell = hRow.createCell((short) i); String colName = field.getAnnotation(ExcelAnnotation.class).name().length>exportType ?field.getAnnotation(ExcelAnnotation.class).name()[exportType] :field.getAnnotation(ExcelAnnotation.class).name()[0]; hCell.setCellValue(colName); hCell.setCellStyle(cellStyle); hSheet.setColumnWidth((short) i, (short) anno.width()); } } } /** * 功能 :設置excel表格默認樣式 * @param hWorkbook 需導出Excel數據 * @param fontHeight 字體粗度 * @param boldWeight 表格線的粗度 * @return */ public HSSFCellStyle getCellStyle(HSSFWorkbook hWorkbook, short fontHeight, short boldWeight) { HSSFCellStyle cellStyle; HSSFFont font; cellStyle = hWorkbook.createCellStyle(); cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN); cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN); cellStyle.setTopBorderColor(HSSFColor.BLACK.index); cellStyle.setLeftBorderColor(HSSFColor.BLACK.index); cellStyle.setRightBorderColor(HSSFColor.BLACK.index); cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); font = hWorkbook.createFont(); font.setFontHeight(fontHeight); font.setBoldweight(boldWeight); font.setFontName("宋體"); cellStyle.setFont(font); cellStyle.setWrapText(true); cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); return cellStyle; } /** * 功能 :設置excel 07表格默認樣式 * @param hWorkbook 需導出Excel數據 * @param fontHeight 字體粗度 * @param boldWeight 表格線的粗度 * @return */ public CellStyle getCellStyle07S(SXSSFWorkbook hWorkbook, short fontHeight, short boldWeight) { CellStyle cellStyle; Font font; cellStyle = hWorkbook.createCellStyle(); cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN); cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN); cellStyle.setTopBorderColor(HSSFColor.BLACK.index); cellStyle.setLeftBorderColor(HSSFColor.BLACK.index); cellStyle.setRightBorderColor(HSSFColor.BLACK.index); cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); font = hWorkbook.createFont(); font.setFontHeight(fontHeight); font.setBoldweight(boldWeight); font.setFontName("宋體"); cellStyle.setFont(font); cellStyle.setWrapText(true); cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); return cellStyle; } /* * 獲取或運算結果 */ private static boolean getHuoResult(Boolean... bs){ for(boolean b:bs){ if(b){ return b; } } return false; } }
4,配置web.xml

<?xml version="1.0" encoding="UTF-8"?> <web-app id="starter" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <servlet-name>ReportExcel</servlet-name> <servlet-class>com.nnkc.ReportExcelTest</servlet-class> </servlet> <servlet-mapping> <servlet-name>ReportExcel</servlet-name> <url-pattern>/reportExcel</url-pattern> </servlet-mapping> </web-app>
5,創建ReportExcel.java用來導出Excel

package com.nnkc; import com.nnkc.util.ExcelUtil; import org.apache.commons.lang.StringUtils; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.List; /** *功能描述:導出報表 */ public class ReportExcel { /** * 功能: Excel導出公共方法 * 記錄條數大於50000時 導出.xlsx文件(excel07+) 小於等於50000時導出 .xls文件(excel97-03) * @param list 需要導出的列表數據 * @param title 導出文件的標題 * @param className 導出對象的類名 * @param exportType 針對同一個pojo可能有多個不同的導出模板時,可以通過此屬性來決定導出哪一套模板,默認第一套 * @param response 用來獲取輸出流 * @param request 針對火狐瀏覽器導出時文件名亂碼的問題,也可以不傳入此值 * @throws IOException */ public void excelExport(List list, String title, Class className, Integer exportType, HttpServletResponse response, HttpServletRequest request) throws IOException { OutputStream out = response.getOutputStream(); try { ExcelUtil excel = new ExcelUtil(); if(list!=null && list.size()>ExcelUtil.EXPORT_07_LEAST_SIZE){ dealBigNumber(list, title, className, exportType, response, request, out, excel); }else{ HSSFWorkbook hss = new HSSFWorkbook(); if(exportType==null){ hss = excel.exportExcel(list,title,className,0); }else{ hss = excel.exportExcel(list, title, className, exportType); } String disposition = "attachment;filename="; if(request!=null&&request.getHeader("USER-AGENT")!=null&& StringUtils.contains(request.getHeader("USER-AGENT"), "Firefox")){ disposition += new String((title+".xls").getBytes(),"ISO8859-1"); }else{ disposition += URLEncoder.encode(title+".xls", "UTF-8"); } response.setContentType("application/vnd.ms-excel;charset=UTF-8"); response.setHeader("Content-disposition", disposition); hss.write(out); } } catch (Exception e) { System.out.println(e.getMessage()); } finally { out.close(); } } private void dealBigNumber(List list, String title, Class className, Integer exportType, HttpServletResponse response, HttpServletRequest request, OutputStream out, ExcelUtil excel) throws Exception{ SXSSFWorkbook hss; if(exportType==null){ hss = excel.exportExcel07S(list,title,className,0); }else{ hss = excel.exportExcel07S(list, title, className, exportType); } String disposition = "attachment;filename="; if(request!=null && request.getHeader("USER-AGENT") != null && StringUtils.contains(request.getHeader("USER-AGENT"), "Firefox")){ disposition += new String((title+".xlsx").getBytes(),"ISO8859-1"); }else{ disposition += URLEncoder.encode(title+".xlsx", "UTF-8"); } response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"); response.setHeader("Content-disposition", disposition); hss.write(out); } }
6最后創建/nnkc-reportexcel/src/main/java/com/nnkc/ReportExcelTest.java用來測試結果

package com.nnkc; import com.nnkc.pojo.Product; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; public class ReportExcelTest extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("調用成功"); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { List<Product> list = new ArrayList<Product>(); for (int i = 0 ; i<60000 ; i++) { //組裝測試數據 Product product = new Product(); product.setName("愛奇藝會員"+i); product.setPrice(9.99); product.setDate(new Date()); list.add(product); } ReportExcel reportExcel = new ReportExcel(); reportExcel.excelExport(list,"測試",Product.class,1,resp,req); } }
運行結果: