JXLS java模板導出excel

剛做完項目稍微總結一下。

我們遇到一個功能的時候常常面臨選擇技術,選不好就掉到坑裏面去了就特麼折騰半天不滿足要求所以很難受,所以對於自己重新接觸的技術真的要了解全面了之後再下手,我寫這個文章是來告訴大家我項目中用到的技術

 

word導出使用freemarker 模板

優點:滿足所有可能的需求

缺點:導出的其實是xml文件而已,只是word高版本支持xml類型的word ,手機是無法打開的,打開就是xml文件。解決辦法網上有一堆,安裝office 使用jacob的jar包加上jacob-1.19-x64.dll文件來調用windows的office轉換成真的word(效率慢的一批),如果哪位大哥知道怎麼解決麻煩告知一下啊。

還有坑巨多,freemarker的語法賊坑,沒有數據就報錯,然後就是你得把word先整理成xml數據(基本上網上的教程不靠譜,你得自己去摸索這個xml的含義)

綜上如果是linux系統部署那你最好還是老老實實用poi吧。

代碼:網上一堆,看不懂那你基本告別這個行業了。

效果:

自己上網去查查這個文檔多複雜,單選,多選,圖片,分頁,頁眉,頁腳(這個是word自帶的功能),都可以滿足你的需求。(就是這個模板你自己得好好看看)


excel導出用jxls模板技術

優點:快,爽

缺點:暫時沒發現,反正比poi爽多了

我以前也一直用poi導出excel,調整間距,excel導出不好看各種麻煩事,直到我發現jxls模板一切變得簡單起來。技術很簡單,幾乎可以滿足你所有excel的需求,所以不要怕大膽用。

貼一個官網http://jxls.sourceforge.net/samples/object_collection_xmlbuilder.html

導入導出我都寫了,導入還是用的poi我覺得導入還是很簡單的。我稍微封裝了一下,代碼貼一下。部分業務代碼不貼。

說一下代碼思路:讀取字段屬性,反射設置對象值,並判斷是否爲字典數據,字典數據通過註解判斷,自己在類上面寫個註解,字典數據替換完事。

jar包貼一下,注意版本,低版本有坑。

<dependency>
    <groupId>org.jxls</groupId>
    <artifactId>jxls-poi</artifactId>
    <version>1.0.16</version>
</dependency>
package com.wenbao.vitwbcrm.utility;


import com.ruoyi.common.config.Global;
import com.wenbao.vitwbcrm.aop.annotation.PoiImportData;
import com.wenbao.vitwbcrm.bkydww.mapper.BaseToolMapper;
import com.wenbao.vitwbcrm.bwg.entity.BaseRelic;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
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;
import org.apache.poi.ss.usermodel.CellType;
import org.jxls.common.Context;
import org.jxls.transform.Transformer;
import org.jxls.transform.poi.PoiTransformer;
import org.jxls.util.JxlsHelper;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Jxls 模板導入導出
 * Created by jhwang
 * Date 2019/3/25 15:54
 */
public class JxlsUtils {

    /**
     * xml文件名稱
     */
    private String xmlName;


    /**
     * xml文件地址
     */
    private String xmlPath;

    /**
     * 數據所在行
     */
    private Integer rowNumber;

    /**
     * 數據所在工作表
     */
    private Integer sheetNumber = 0;


    /**
     * 設置是否生成主鍵,默認true
     */
    private boolean ifcreateId = true;


    /**
     * 主鍵默認字段
     */
    private String id = "id";


    public BaseToolMapper baseToolMapper;


    public JxlsUtils() {}

    /**
     * @param xmlName 模板名稱
     * @param rowNumber 對應數據開始行
     */
    public JxlsUtils(String xmlName,Integer rowNumber) {
        this.xmlName = xmlName;
        this.rowNumber = rowNumber;
        //獲取默認文件夾下的文件
        this.xmlPath = FileUtils.getPath("jxlsxml"+"/"+xmlName.replace(File.separator,""));
    }

    /**
     * 讀取office表格中的數據
     * @param xmlName 模板名稱
     * @return
     */
    private static Object readOfficeDataStatic(String xmlName, String tableName,Integer rowNumber,Class cls, InputStream inp){
        JxlsUtils jxlsUtils = new JxlsUtils(xmlName,tableName,rowNumber);
        return jxlsUtils.readPoiOfficeData(cls,inp);
    }



    /**
     * 基於poi讀取office表格中的數據
     * @param  inputStream 讀取的文件流數據,
     * @return
     */
    public Object readPoiOfficeData(Class cls,InputStream inputStream){
        List<Object> list = new ArrayList<Object>();
        //獲取所有的字段
        Map xmlMap = getXmlMap();
        HSSFWorkbook workbook = null;
        try {
            workbook = new HSSFWorkbook(inputStream);
            HSSFSheet hssfSheet = workbook.getSheetAt(this.sheetNumber);
            //循環行
            for (int rowNum = this.rowNumber; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
                HSSFRow hssfRow = hssfSheet.getRow(rowNum);
                if (hssfRow == null ) {
                    continue;
                }
                Object o = cls.newInstance();
                for (int rowi = 0; rowi <= hssfRow.getLastCellNum(); rowi++) {
                    HSSFCell cell = hssfRow.getCell(rowi);
                    if (cell == null) {
                        continue;
                    }
                    //讀取數據前設置單元格類型
                    cell.setCellType(CellType.STRING);
                    String value = cell.getStringCellValue();
                    if(xmlMap.get(rowi) != null){
                        BeanUtils.setProperty(o, (String) xmlMap.get(rowi), value);
                    }
                }
                //如果爲null則結束循環
                if(ifBenanNull(o)){
                    return list;
                }
                //是否生成主鍵
                if(ifcreateId){
                    BeanUtils.setProperty(o, this.id, Uuid.AddUUid());
                }
                list.add(o);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 基於jxls模板導出數據
     * @param  list 導出數據集合
     * @return
     */
    public String exportExcel(List list) throws IOException {
        //模板遍歷對象
        String examList = "examList";
        //文件臨時存放地址
        String fileName = DateUtils.getYYYYMMDD()+".xlsx";
        File out = new File( Global.getDownloadPath()+fileName);
        Context context =  PoiTransformer.createInitialContext();
        context.putVar(examList, list);
        JxlsHelper jxlsHelper = JxlsHelper.getInstance();
        Transformer transformer  = jxlsHelper.createTransformer(new FileInputStream(this.xmlPath), new FileOutputStream(out));
        jxlsHelper.processTemplate(context, transformer);
        return fileName;
    }



    /**
     * 基於jxls模板導出數據 橫向數據導出
     * @param rowlist 橫向數據
     * @param datalist 集合數據
     * @return
     */
    public String exportExcelRow(List rowlist,List datalist) throws IOException {
//        try(InputStream is = GridCommandDemo.class.getResourceAsStream("grid_template.xls")) {
//            try(OutputStream os = new FileOutputStream("target/grid_output2.xls")) {
//                Context context = new Context();
//                context.putVar("rowlist", Arrays.asList("Name", "Birthday", "Payment"));
//                context.putVar("datalist", employees);
//                JxlsHelper.getInstance().processGridTemplateAtCell(is, os, context, "name,birthDate,payment", "Sheet2!A1");
//            }
//        }
        return null;
    }



    /**
     * 判斷對象是否全部爲null 或者“”,如果是返回true 否返回false
     * @param obj
     * @return
     * @throws IllegalAccessException
     */
    private boolean ifBenanNull(Object obj)  {
        boolean flag = true;
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for(Field f : declaredFields){
            f.setAccessible(true);
            try {
                if("serialVersionUID".equals(f.getName())){
                    continue;
                }
                if(BeanUtils.getProperty(obj,f.getName()) != null && !"".equals(BeanUtils.getProperty(obj,f.getName()))){
                    return false;
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        return flag;
    }


    /**
     * 獲取xml文件中所設置的字段返回map
     * key - 字段名稱
     * value - 字段所屬位置
     */
    private Map getXmlMap(){
        Map<Integer, String> map = new HashMap<>();
        HSSFWorkbook workbook = null;
        try {
            // 讀取Excel文件
            FileInputStream fileInputStream = new FileInputStream(this.xmlPath);
            workbook = new HSSFWorkbook(fileInputStream);
            HSSFSheet hssfSheet = workbook.getSheetAt(this.sheetNumber);
            HSSFRow row = hssfSheet.getRow(this.rowNumber);
            // 循環列
            for (int rowNum = 0; rowNum <= row.getLastCellNum(); rowNum++) {
                HSSFCell cell = row.getCell(rowNum);
                if (cell == null) {
                    continue;
                }
                cell.setCellType(CellType.STRING);
                if(cell.getStringCellValue() != null && !"".equals(cell.getStringCellValue())){
                    String value = formatParamCode(cell.getStringCellValue()).split("\\.")[1];
                    if(value!=null && !"".equals(value)){
                        map.put(rowNum,value);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 取出${}中的數據
     * @param paramCode
     * @return
     */
    public String formatParamCode(String paramCode){
        return paramCode.replaceAll("\\$", "").replaceAll("\\{", "").replaceAll("\\}", "");
    }


    /**
     * 根據導出對象上的註解 PoiImportData 設置轉換成對應的字典數據
     */
    public void processingCodeData(List list, BaseToolMapper baseToolMapper) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        for (Object obj:list) {
            Map<String, Object> describe = PropertyUtils.describe(obj);
            for (String key : describe.keySet()) {
                //排除掉默認的class
                if(key.equals("class")){
                    continue;
                }
                if(describe.get(key) != null && !describe.get(key).toString().trim().equals("")){
                    //獲取註解
                    PoiImportData annotation = obj.getClass().getDeclaredField(key).getAnnotation(PoiImportData.class);
                    if(annotation != null){
                        //表名
                        String tableName = annotation.tableName();
                        //主鍵
                        String id = annotation.id();
                        //value、
                        String value = annotation.value();
                        String s = baseToolMapper.selectCodeID(tableName, id, value, (String) describe.get(key));
                        BeanUtils.setProperty(obj,key,s);
                    }
                }
                
            }
        }
    }


    public static void main(String[] ags) throws IllegalAccessException, Exception {
        JxlsUtils jxlsUtils = new JxlsUtils("可移動文物標準模板.xls",  3);
        try {
            FileInputStream fileInputStream = new FileInputStream("D:\\青海項目\\各市州一普資料\\63232441900003河南蒙古族自治縣拉卡寺.xls");
            //導入
            List<BaseRelic> list = (List<BaseRelic>)jxlsUtils.readPoiOfficeData(BaseRelic.class, fileInputStream);
            //導出
            jxlsUtils.exportExcel(list);
        } catch (Exception e) {
            e.printStackTrace();
        }
//        JxlsUtils jxlsUtils = new JxlsUtils();
//        BaseRelic baseRelic = new BaseRelic();
//        //baseRelic.setgId("11");
//        boolean b = jxlsUtils.ifBenanNull(baseRelic);
//        System.out.println(b);
    }


}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章