POI操作Excel导入和导出

jopen 3年前

Apache的POI组件是Java操作Microsoft Office办公套件的强大API,其中对Word,Excel和PowperPoint都有支持,当然使用较多的还是Excel,因为Word和PowerPoint用程序动态操作的应用较少。那么本文就结合POI来介绍一下操作Excel的方法。 

这里介绍两种方法实现excel的操作。代码都有注释,可以很清楚的看懂,一种是循环遍历excel表格,这个要自己定位一个excel的起点。另外一种是通过java反射机制实现的,根据表头来实现映射。具体代码如下:

第一种:

import java.io.BufferedInputStream;  import java.io.File;  import java.io.FileInputStream;  import java.io.FileNotFoundException;  import java.io.IOException;  import java.text.DecimalFormat;  import java.text.SimpleDateFormat;  import java.util.ArrayList;  import java.util.Arrays;  import java.util.Date;  import java.util.List;    import org.apache.poi.hssf.usermodel.HSSFCell;  import org.apache.poi.hssf.usermodel.HSSFDateUtil;  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.poifs.filesystem.POIFSFileSystem;        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.util.Region;      public class ExcelUtils {      /**    * 读取EXCEL    * @param firstrow 从第几行开始读取    * @return 读取后返回数组    */   @SuppressWarnings("deprecation")   public static String[][] importExcel(File file, int firstrow)     throws FileNotFoundException, IOException {    List<String[]> result = new ArrayList<String[]>();    int rowSize = 0;    BufferedInputStream in = new BufferedInputStream(new FileInputStream(      file));    POIFSFileSystem fs = new POIFSFileSystem(in);    HSSFWorkbook wb = new HSSFWorkbook(fs);    HSSFCell cell = null;    for (int sheetIndex = 0; sheetIndex < wb.getNumberOfSheets(); sheetIndex++) {     HSSFSheet st = wb.getSheetAt(sheetIndex);     for (int rowIndex = firstrow; rowIndex <= st.getLastRowNum(); rowIndex++) {      HSSFRow row = st.getRow(rowIndex);      if (row == null) {       continue;      }      int tempRowSize = row.getLastCellNum() + 1;      if (tempRowSize > rowSize) {       rowSize = tempRowSize;      }      String[] values = new String[rowSize];      Arrays.fill(values, "");      boolean hasValue = false;        for (short columnIndex = 0; columnIndex <= row.getLastCellNum(); columnIndex++) {       String value = "";       cell = row.getCell(columnIndex);       if (cell != null) {        switch (cell.getCellType()) {        case HSSFCell.CELL_TYPE_STRING://读取的格式为字符串         value = cell.getStringCellValue();         break;        case HSSFCell.CELL_TYPE_NUMERIC://读取的格式为数组         //如果格式为日期格式,自定义格式输出         if (HSSFDateUtil.isCellDateFormatted(cell)) {          Date date = cell.getDateCellValue();          if (date != null) {           value = new SimpleDateFormat("yyyy-MM-dd")             .format(date);          } else {           value = "";          }         } else {          //如果格式为数值,自定义格式输出          value = new DecimalFormat().format(cell            .getNumericCellValue());         }         break;        case HSSFCell.CELL_TYPE_FORMULA:         // 导入时如果为公式生成的数据则无值         value = "";         break;         // 导入时如果为空        case HSSFCell.CELL_TYPE_BLANK:         break;        case HSSFCell.CELL_TYPE_ERROR:         value = "";         break;         // 导入时如果为BOOLEAN型 自定义格式输出        case HSSFCell.CELL_TYPE_BOOLEAN:         value = (cell.getBooleanCellValue() == true ? "Y"           : "N");         break;        default:         value = "";        }       }         values[columnIndex] = rightTrim(value);       hasValue = true;      }        if (hasValue) {       result.add(values);      }     }       in.close();     String[][] returnArray = new String[result.size()][rowSize];     for (int i = 0; i < returnArray.length; i++) {      returnArray[i] = (String[]) result.get(i);     }     return returnArray;    }    return null;     }     /**    * 去掉字符串右边的空格    *     * @param str 要处理的字符串    * @return 处理后的字符串    */   public static String rightTrim(String str) {    if (str == null) {     return "";    }    int length = str.length();    for (int i = length - 1; i >= 0; i--) {     if (str.charAt(i) != 0x20) {      break;     }     length--;    }    return str.substring(0, length);   }     /**    * 创建通用EXCEL头部    *     * @param headString 头部显示的字符    * @param colSum 该报表的列数    */   @SuppressWarnings("deprecation")   public void createNormalHead(String headString, int colSum,HSSFSheet sheet,HSSFWorkbook wb) {           HSSFRow row1 = sheet.createRow(0);      // 设置第一行    HSSFCell cell = row1.createCell(0);    row1.setHeight((short) 800);      // 定义单元格为字符串类型    cell.setCellType(HSSFCell.ENCODING_UTF_16);    cell.setCellValue(new HSSFRichTextString(headString));      // 指定合并区域    sheet.addMergedRegion(new Region(0, (short) 0, 0, (short) colSum));      HSSFCellStyle cellStyle = wb.createCellStyle();      cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 指定单元格居中对齐    cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 指定单元格垂直居中对齐    //cellStyle.setWrapText(true);// 指定单元格自动换行      // 设置单元格字体    HSSFFont font = wb.createFont();    font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);    font.setFontName("宋体");    font.setFontHeight((short) 300);    cellStyle.setFont(font);      cell.setCellStyle(cellStyle);   }      /**    * 创建通用报表第二行的格式    *     */   public HSSFCellStyle getCellStyle(HSSFWorkbook wb) {    // 创建单元格样式     HSSFCellStyle cellStyle = wb.createCellStyle();     // 指定单元格居中对齐     cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);     // 指定单元格垂直居中对齐     cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);     // 指定当单元格内容显示不下时自动换行     //cellStyle.setWrapText(true);     // 设置单元格字体     HSSFFont font = wb.createFont();     font.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);     font.setFontName("宋体");     font.setFontHeight((short) 200);     //font.setFontHeightInPoints((short) 22);     cellStyle.setFont(font);     return cellStyle;     }     }

第二种:

import java.io.File;  import java.io.FileInputStream;  import java.io.IOException;  import java.io.OutputStream;  import java.lang.reflect.Field;  import java.lang.reflect.Method;  import java.lang.reflect.Type;  import java.text.SimpleDateFormat;  import java.util.ArrayList;  import java.util.Collection;  import java.util.Date;  import java.util.HashMap;  import java.util.Iterator;  import java.util.List;  import java.util.Map;    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.hssf.util.HSSFColor;  import org.apache.poi.ss.usermodel.Cell;  import org.apache.poi.ss.usermodel.CellStyle;  import org.apache.poi.ss.usermodel.Row;  import org.apache.poi.ss.util.CellRangeAddress;    public class ExcelUtil<T> {   /**    * 从excel导入,返回一个list集合    *     * @author     * @param file    *            导入的excel文件    * @param pattern    * @return    * */   Class<T> clazz;     public ExcelUtil(Class<T> clazz) {    this.clazz = clazz;   }     @SuppressWarnings("unchecked")   public Collection<T> importExcel(File file, String... pattern)     throws Exception {    Collection<T> dist = new ArrayList<T>();    try {     /**      * 类反射得到调用方法      */     // 得到目标目标类的所有的字段列表     Field filed[] = clazz.getDeclaredFields();     // 将所有标有Annotation的字段,也就是允许导入数据的字段,放入到一个map中     Map fieldmap = new HashMap();     // 循环读取所有字段     for (int i = 0; i < filed.length; i++) {      Field f = filed[i];      // 得到单个字段上的Annotation      ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class);      // 如果标识了Annotationd的话      if (exa != null) {       // 构造设置了Annotation的字段的Setter方法       String fieldname = f.getName();       String setMethodName = "set"         + fieldname.substring(0, 1).toUpperCase()         + fieldname.substring(1);       // 构造调用的method,       Method setMethod = clazz.getMethod(setMethodName,         new Class[] { f.getType() });       // 将这个method以Annotaion的名字为key来存入。       fieldmap.put(exa.exportName(), setMethod);      }     }     /**      * excel的解析开始      */     // 将传入的File构造为FileInputStream;     FileInputStream in = new FileInputStream(file);     // // 得到工作表     HSSFWorkbook book = new HSSFWorkbook(in);     // // 得到第一页     HSSFSheet sheet = book.getSheetAt(0);     // // 得到第一面的所有行     Iterator<Row> row = sheet.rowIterator();       /**      * 标题解析      */     // 得到第一行,也就是标题行     Row title = row.next();     // 得到第一行的所有列     Iterator<Cell> cellTitle = title.cellIterator();     // 将标题的文字内容放入到一个map中。     Map titlemap = new HashMap();     // 从标题第一列开始     int i = 0;     // 循环标题所有的列     while (cellTitle.hasNext()) {      Cell cell = cellTitle.next();      String value = cell.getStringCellValue();      // 还是把表头trim一下      value = value.trim();      titlemap.put(i, value);      i = i + 1;     }     /**      * 解析内容行      */     // 用来格式化日期的DateFormat     SimpleDateFormat sf;     if (pattern.length < 1) {      sf = new SimpleDateFormat("yyyy-MM-dd");     } else      sf = new SimpleDateFormat(pattern[0]);     while (row.hasNext()) {      // 标题下的第一行      Row rown = row.next();        // 行的所有列      Iterator<Cell> cellbody = rown.cellIterator();      // 得到传入类的实例      T tObject = clazz.newInstance();      int k = 0;      // 遍历一行的列      while (cellbody.hasNext()) {       Cell cell = cellbody.next();       // 这里得到此列的对应的标题       String titleString = (String) titlemap.get(k);       // 如果这一列的标题和类中的某一列的Annotation相同,那么则调用此类的的set方法,进行设值       if (fieldmap.containsKey(titleString)) {        Method setMethod = (Method) fieldmap.get(titleString);        // 得到setter方法的参数        Type[] ts = setMethod.getGenericParameterTypes();        // 只要一个参数        String xclass = ts[0].toString();        // 判断参数类型        try {         switch (cell.getCellType()) {         case HSSFCell.CELL_TYPE_NUMERIC: // 数字          if (xclass.equals("class java.lang.String")) {           if ((cell.getNumericCellValue() + "")             .indexOf(".") > 0) {            setMethod              .invoke(tObject,                (cell.getNumericCellValue() + "")                  .substring(                    0,                    (cell.getNumericCellValue() + "")                      .lastIndexOf(".")));           }          } else if (xclass            .equals("class java.lang.Integer")) {           setMethod.invoke(tObject,             (int) cell.getNumericCellValue());          } else if (xclass.equals("int")) {           setMethod.invoke(tObject,             (int) cell.getNumericCellValue());          }          break;         case HSSFCell.CELL_TYPE_STRING: // 字符串          if (xclass.equals("class java.lang.Integer")) {           setMethod.invoke(tObject,             Integer.parseInt(cell               .getStringCellValue()));          } else if (xclass            .equals("class java.lang.String")) {           setMethod.invoke(tObject, cell             .getStringCellValue().trim());          } else if (xclass.equals("int")) {           int temp = Integer.parseInt(cell             .getStringCellValue());           setMethod.invoke(tObject, temp);          }          break;         case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean          Boolean boolname = true;          if (cell.getStringCellValue().equals("否")) {           boolname = false;          }          setMethod.invoke(tObject, boolname);          break;         case HSSFCell.CELL_TYPE_FORMULA: // 公式          System.out.print(cell.getCellFormula() + "   ");          break;         case HSSFCell.CELL_TYPE_BLANK: // 空值          System.out.println(" ");          break;         case HSSFCell.CELL_TYPE_ERROR: // 故障          System.out.println(" ");          break;         default:          System.out.print("未知类型   ");          break;         }        } catch (Exception e) {// 转换出错         e.printStackTrace();          }       }       // 下一列       k = k + 1;      }      dist.add(tObject);     }    } catch (Exception e) {     e.printStackTrace();     // 将异常抛出去     throw e;    }    return dist;   }     // 格式化日期   SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");     /**    * 导出到excel中去,    *     * @author Administrator    * @param title    *            excel的工作表名    * @param fileName    *            excel 文件名    * @param dateset    *            导出的数据集合    * @param out    *            输出流    * @throws IOException    */   @SuppressWarnings({ "static-access" })   public void exportExcel(String title, String fileName, List<T> dataset, String totalMoney,     HttpServletResponse response) throws IOException {    OutputStream out = response.getOutputStream();// 取得输出流    response.reset();// 清空输出流    response.setContentType("application/ms-excel;charset=GB2312");    response.setHeader("Content-disposition", "attachment; filename="      + new String(fileName.getBytes("gb2312"), "iso8859-1") + ".xls");    // 声明一个工作薄    try {     HSSFWorkbook workbook = new HSSFWorkbook();     // 首先检查数据看是否是正确的     if (dataset == null || dataset.size() == 0 || title == null       || out == null) {      throw new Exception("传入的数据不对!");     }     // 取得实际泛型类     T ts = (T) dataset.get(0);     Class<?> tCls = ts.getClass();     // 生成一个表格     HSSFSheet sheet = workbook.createSheet(title);     // 设置表格默认列宽度为15个字节     sheet.setDefaultColumnWidth(15);     // 生成一个样式     HSSFCellStyle style = workbook.createCellStyle();     // 设置标题样式     style = this.setHeadStyle(workbook, style);       // 得到所有字段       Field filed[] = ts.getClass().getDeclaredFields();     // 标题     List<String> exportfieldtile = new ArrayList<String>();     // 导出的字段的get方法     List<Method> methodObj = new ArrayList<Method>();     // 遍历整个filed     for (int i = 0; i < filed.length; i++) {      Field f = filed[i];      ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class);      // 如果设置了annottion      if (exa != null) {       String exprot = exa.exportName();       // 添加到标题       exportfieldtile.add(exprot);       // 添加到需要导出的字段的方法       String fieldname = f.getName();       String getMethodName = "get"         + fieldname.substring(0, 1).toUpperCase()         + fieldname.substring(1);         Method getMethod = tCls.getMethod(getMethodName,         new Class[] {});         methodObj.add(getMethod);      }     }     sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, exportfieldtile       .size() - 1));     HSSFRow titleRow = sheet.createRow(0);     HSSFCell titleCell = titleRow.createCell(0);     titleCell.setCellValue(title);     titleCell.setCellStyle(this.setTitleStyle(workbook,       workbook.createCellStyle()));     // 产生表格标题行     HSSFRow row = sheet.createRow(1);     for (int i = 0; i < exportfieldtile.size(); i++) {      HSSFCell cell = row.createCell(i);      cell.setCellStyle(style);      HSSFRichTextString text = new HSSFRichTextString(        exportfieldtile.get(i));      cell.setCellValue(text);     }       int index = 1;       // 循环整个list     for (int j = 0; j < dataset.size(); j++) {      // 从第二行开始写,第一行是标题      T t = (T) dataset.get(j);      row = sheet.createRow(index + 1);      for (int k = 0; k < methodObj.size(); k++) {       HSSFCell cell = row.createCell(k);       Method getMethod = methodObj.get(k);       Object value = getMethod.invoke(t, new Object[] {});       String textValue = getValue(value);       cell.setCellValue(textValue);      }      index++;     }          //总的项目笔数     HSSFRow totalNumRow = sheet.createRow(index + 2);     HSSFCell totalNumCellTitle = totalNumRow.createCell(0);     totalNumCellTitle.setCellStyle(setStatStyle(workbook, workbook.createCellStyle()));     totalNumCellTitle.setCellValue("项目笔数");     HSSFCell totalNumCell = totalNumRow.createCell(1);     totalNumCell.setCellStyle(setStatStyle(workbook, workbook.createCellStyle()));     totalNumCell.setCellValue(dataset.size());          //总金额     HSSFRow totalMoneyRow = sheet.createRow(index + 3);     HSSFCell totalMoneyCellTitle = totalMoneyRow.createCell(0);     totalMoneyCellTitle.setCellStyle(setStatStyle(workbook, workbook.createCellStyle()));     totalMoneyCellTitle.setCellValue("总金额");     HSSFCell totalMoneyCell = totalMoneyRow.createCell(1);     totalMoneyCell.setCellStyle(setStatStyle(workbook, workbook.createCellStyle()));     totalMoneyCell.setCellValue(totalMoney + "万元");     workbook.write(out);    } catch (Exception e) {     e.printStackTrace();    }     }     public String getValue(Object value) {    String textValue = "";    if (value == null)     return textValue;      if (value instanceof Boolean) {     boolean bValue = (Boolean) value;     textValue = "是";     if (!bValue) {      textValue = "否";     }    } else if (value instanceof Date) {     Date date = (Date) value;       textValue = sdf.format(date);    } else     textValue = value.toString();      return textValue;   }     /**    * 初始化导出的excel标题的样式    * */   public static HSSFCellStyle setTitleStyle(HSSFWorkbook workbook,     HSSFCellStyle style) {      style.setFillForegroundColor(HSSFColor.WHITE.index);            style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);            style.setBorderBottom(HSSFCellStyle.BORDER_THIN);            style.setBorderLeft(HSSFCellStyle.BORDER_THIN);            style.setBorderRight(HSSFCellStyle.BORDER_THIN);            style.setBorderTop(HSSFCellStyle.BORDER_THIN);            style.setAlignment(HSSFCellStyle.ALIGN_CENTER);            // 生成字体            HSSFFont font = workbook.createFont();            font.setColor(HSSFColor.BLACK.index);            font.setFontHeightInPoints((short) 16);            font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);            // 把字体应用到当前的样样式            style.setFont(font);            return style;     }      /**    * 统计部分的样式    * @param workbook    * @param style    * @return    */   public static HSSFCellStyle setStatStyle(HSSFWorkbook workbook,     HSSFCellStyle style) {        style.setFillForegroundColor(HSSFColor.WHITE.index);    style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);    style.setBorderBottom(HSSFCellStyle.BORDER_NONE);    style.setBorderLeft(HSSFCellStyle.BORDER_NONE);    style.setBorderRight(HSSFCellStyle.BORDER_NONE);    style.setBorderTop(HSSFCellStyle.BORDER_NONE);    style.setAlignment(HSSFCellStyle.ALIGN_LEFT);    // 生成字体    HSSFFont font = workbook.createFont();    font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);    // 把字体应用到当前的样样式    style.setFont(font);    return style;       }     /**    * 初始化导出的excel样式    * */   public static HSSFCellStyle setHeadStyle(HSSFWorkbook workbook,     HSSFCellStyle style) {      style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);            style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);            style.setBorderBottom(HSSFCellStyle.BORDER_THIN);            style.setBorderLeft(HSSFCellStyle.BORDER_THIN);            style.setBorderRight(HSSFCellStyle.BORDER_THIN);            style.setBorderTop(HSSFCellStyle.BORDER_THIN);            style.setAlignment(HSSFCellStyle.ALIGN_CENTER);            // 生成字体            HSSFFont font = workbook.createFont();            font.setColor(HSSFColor.VIOLET.index);            font.setFontHeightInPoints((short) 12);            font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);            // 把字体应用到当前的样样式            style.setFont(font);            return style;       }     public static HSSFCellStyle setbodyStyle(HSSFWorkbook workbook,     HSSFCellStyle style2) {    style2.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);            style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);            style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);            style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);            style2.setBorderRight(HSSFCellStyle.BORDER_THIN);            style2.setBorderTop(HSSFCellStyle.BORDER_THIN);            style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);            style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);            // 生成字体            HSSFFont font2 = workbook.createFont();            font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);            // 把字体应用到当前的样样式            style2.setFont(font2);            return style2;   }  }


import java.lang.annotation.ElementType;  import java.lang.annotation.Retention;  import java.lang.annotation.RetentionPolicy;  import java.lang.annotation.Target;  /**   * 用于Excel导出时给每个pojo对象的字段添加字段名称,作为excel的表头   *    * */  @Retention(RetentionPolicy.RUNTIME)    @Target(ElementType.FIELD)    public @interface ExcelAnnotation {        // excel导出时标题显示的名字,如果没有设置Annotation属性,将不会被导出和导入        public String exportName();    }




来自: http://blog.csdn.net//u011067360/article/details/24416541