關於excel表格的導入導出的工具類。(java 反射 excel)


先導文:寫完上一篇文章,被我家吾皇訓斥了許久。為了表達的我歉意,特意附上一篇工具包。

以下是工具包代碼:

package web;

import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class ExeclUtil {
    static int sheetsize = 5000;

    /**
     * @author Lyy
     * @param data
     *            導入到excel中的數據
     * @param out
     *            數據寫入的文件
     * @param fields
     *            需要注意的是這個方法中的map中:每一列對應的實體類的英文名為鍵,excel表格中每一列名為值
     * @throws Exception
     */
    public static <T> void ListtoExecl(List<T> data, OutputStream out,
            Map<String, String> fields) throws Exception {
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 如果導入數據為空,則拋出異常。
        if (data == null || data.size() == 0) {
            workbook.close();
            throw new Exception("導入的數據為空");
        }
        // 根據data計算有多少頁sheet
        int pages = data.size() / sheetsize;
        if (data.size() % sheetsize > 0) {
            pages += 1;
        }
        // 提取表格的字段名(英文字段名是為了對照中文字段名的)
        String[] egtitles = new String[fields.size()];
        String[] cntitles = new String[fields.size()];
        Iterator<String> it = fields.keySet().iterator();
        int count = 0;
        while (it.hasNext()) {
            String egtitle = (String) it.next();
            String cntitle = fields.get(egtitle);
            egtitles[count] = egtitle;
            cntitles[count] = cntitle;
            count++;
        }
        // 添加數據
        for (int i = 0; i < pages; i++) {
            int rownum = 0;
            // 計算每頁的起始數據和結束數據
            int startIndex = i * sheetsize;
            int endIndex = (i + 1) * sheetsize - 1 > data.size() ? data.size()
                    : (i + 1) * sheetsize - 1;
            // 創建每頁,並創建第一行
            HSSFSheet sheet = workbook.createSheet();
            HSSFRow row = sheet.createRow(rownum);

            // 在每頁sheet的第一行中,添加字段名
            for (int f = 0; f < cntitles.length; f++) {
                HSSFCell cell = row.createCell(f);
                cell.setCellValue(cntitles[f]);
            }
            rownum++;
            // 將數據添加進表格
            for (int j = startIndex; j < endIndex; j++) {
                row = sheet.createRow(rownum);
                T item = data.get(j);
                for (int h = 0; h < cntitles.length; h++) {
                    Field fd = item.getClass().getDeclaredField(egtitles[h]);
                    fd.setAccessible(true);
                    Object o = fd.get(item);
                    String value = o == null ? "" : o.toString();
                    HSSFCell cell = row.createCell(h);
                    cell.setCellValue(value);
                }
                rownum++;
            }
        }
        // 將創建好的數據寫入輸出流
        workbook.write(out);
        // 關閉workbook
        workbook.close();
    }
  /**
   * @author Lyy
   * @param entityClass excel中每一行數據的實體類
   * @param in          excel文件
   * @param fields     字段名字
   *             需要注意的是這個方法中的map中:
   *             excel表格中每一列名為鍵,每一列對應的實體類的英文名為值
   * @throws Exception
   */
public static <T> List<T> ExecltoList(InputStream in, Class<T> entityClass, Map<String, String> fields) throws Exception { List<T> resultList = new ArrayList<T>(); HSSFWorkbook workbook = new HSSFWorkbook(in); // excel中字段的中英文名字數組 String[] egtitles = new String[fields.size()]; String[] cntitles = new String[fields.size()]; Iterator<String> it = fields.keySet().iterator(); int count = 0; while (it.hasNext()) { String cntitle = (String) it.next(); String egtitle = fields.get(cntitle); egtitles[count] = egtitle; cntitles[count] = cntitle; count++; } // 得到excel中sheet總數 int sheetcount = workbook.getNumberOfSheets(); if (sheetcount == 0) { workbook.close(); throw new Exception("Excel文件中沒有任何數據"); } // 數據的導出 for (int i = 0; i < sheetcount; i++) { HSSFSheet sheet = workbook.getSheetAt(i); if (sheet == null) { continue; } // 每頁中的第一行為標題行,對標題行的特殊處理 HSSFRow firstRow = sheet.getRow(0); int celllength = firstRow.getLastCellNum(); String[] excelFieldNames = new String[celllength]; LinkedHashMap<String, Integer> colMap = new LinkedHashMap<String, Integer>(); // 獲取Excel中的列名 for (int f = 0; f < celllength; f++) { HSSFCell cell = firstRow.getCell(f); excelFieldNames[f] = cell.getStringCellValue().trim(); // 將列名和列號放入Map中,這樣通過列名就可以拿到列號 for (int g = 0; g < excelFieldNames.length; g++) { colMap.put(excelFieldNames[g], g); } } // 由於數組是根據長度創建的,所以值是空值,這里對列名map做了去空鍵的處理 colMap.remove(null); // 判斷需要的字段在Excel中是否都存在 // 需要注意的是這個方法中的map中:中文名為鍵,英文名為值 boolean isExist = true; List<String> excelFieldList = Arrays.asList(excelFieldNames); for (String cnName : fields.keySet()) { if (!excelFieldList.contains(cnName)) { isExist = false; break; } } // 如果有列名不存在,則拋出異常,提示錯誤 if (!isExist) { workbook.close(); throw new Exception("Excel中缺少必要的字段,或字段名稱有誤"); } // 將sheet轉換為list for (int j = 1; j <= sheet.getLastRowNum(); j++) { HSSFRow row = sheet.getRow(j); // 根據泛型創建實體類 T entity = entityClass.newInstance(); // 給對象中的字段賦值 for (Entry<String, String> entry : fields.entrySet()) { // 獲取中文字段名 String cnNormalName = entry.getKey(); // 獲取英文字段名 String enNormalName = entry.getValue(); // 根據中文字段名獲取列號 int col = colMap.get(cnNormalName); // 獲取當前單元格中的內容 String content = row.getCell(col).toString().trim(); // 給對象賦值 setFieldValueByName(enNormalName, content, entity); } resultList.add(entity); } } workbook.close(); return resultList; } /** * @MethodName : setFieldValueByName * @Description : 根據字段名給對象的字段賦值 * @param fieldName * 字段名 * @param fieldValue * 字段值 * @param o * 對象 */ private static void setFieldValueByName(String fieldName, Object fieldValue, Object o) throws Exception { Field field = getFieldByName(fieldName, o.getClass()); if (field != null) { field.setAccessible(true); // 獲取字段類型 Class<?> fieldType = field.getType(); // 根據字段類型給字段賦值 if (String.class == fieldType) { field.set(o, String.valueOf(fieldValue)); } else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) { field.set(o, Integer.parseInt(fieldValue.toString())); } else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) { field.set(o, Long.valueOf(fieldValue.toString())); } else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) { field.set(o, Float.valueOf(fieldValue.toString())); } else if ((Short.TYPE == fieldType) || (Short.class == fieldType)) { field.set(o, Short.valueOf(fieldValue.toString())); } else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) { field.set(o, Double.valueOf(fieldValue.toString())); } else if (Character.TYPE == fieldType) { if ((fieldValue != null) && (fieldValue.toString().length() > 0)) { field.set(o, Character.valueOf(fieldValue.toString().charAt(0))); } } else if (Date.class == fieldType) { field.set(o, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") .parse(fieldValue.toString())); } else { field.set(o, fieldValue); } } else { throw new Exception(o.getClass().getSimpleName() + "類不存在字段名 " + fieldName); } } /** * @MethodName : getFieldByName * @Description : 根據字段名獲取字段 * @param fieldName * 字段名 * @param clazz * 包含該字段的類 * @return 字段 */ private static Field getFieldByName(String fieldName, Class<?> clazz) { // 拿到本類的所有字段 Field[] selfFields = clazz.getDeclaredFields(); // 如果本類中存在該字段,則返回 for (Field field : selfFields) { if (field.getName().equals(fieldName)) { return field; } } // 否則,查看父類中是否存在此字段,如果有則返回 Class<?> superClazz = clazz.getSuperclass(); if (superClazz != null && superClazz != Object.class) { return getFieldByName(fieldName, superClazz); } // 如果本類和父類都沒有,則返回空 return null; } }

以下是該工具包的使用:

 

 1 public class TestController {
 2 
 3     @RequestMapping("lytest.do")
 4     public String test(HttpServletRequest req, Student stu1) throws Exception {
 5         List<Student> li = new ArrayList<Student>();
 6         li.add(stu1);
 7         OutputStream out = new FileOutputStream("d://aa.xls");
 8         Map<String, String> fields = new HashMap<String, String>();
 9         fields.put("uid", "學號");
10         fields.put("uname", "姓名");
11         fields.put("sex", "性別");
12         fields.put("nation", "民族");
13         ExeclUtil.ListtoExecl(li, out, fields);
14         out.close();
15         return "index";
16     }
17 
18     @RequestMapping("lytest1.do")
19     public String test1(ModelMap mm) throws Exception {
20         InputStream in = new FileInputStream("d://aa.xls");
21         Map<String, String> fieldd = new HashMap<String, String>();
22         fieldd.put("學號", "uid");
23         fieldd.put("姓名", "uname");
24         fieldd.put("性別", "sex");
25         fieldd.put("民族", "nation");
26         List<Student> resultList = new ArrayList<Student>();
27         resultList = ExeclUtil.ExecltoList(in, Student.class, fieldd);
28         mm.put("lists", resultList);
29         return "index";
30     }
31 
32 }

 

 

 

-------------------------------------------------------------------我是分隔符--------------------------------------------------------------------------------------

 

我家吾皇,我知道 你不知道怎么插入代碼。

特此附圖一張

 

 

-------------------------------------------------------------------我是分隔符--------------------------------------------------------------------------------------

 

請不要說我家吾皇傻,平時不開口,看不出來的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM