HAP Excel導入導出功能總結

基本導入導出的文檔入口:https://rdc.hand-china.com/gitlab/HAP/hap-developer-guide/blob/master/excel.md

1、標準 Excel 導出

<span class="btn btn-primary " style="float:left;margin-right:5px;" data-bind="click:exportExcel">
	<i class="fa fa-file-excel-o" style="margin-right:3px;">
	</i><@spring.message "hap.exportexcel"/>
</span>

2、標準 Excel 導入

<span class="btn btn-primary k-grid-excel" style="float:left;" onclick='Hap.importExcel("table_name")' >
	<i class="fa fa-arrow-circle-up" style="margin-right:3px;">
	</i><@spring.message "excel.import"/>
</span>

其中 table_name 是要導入的數據表名,如 sys_code_b

3、自定義 Excel 導出:

詳細參考官方文檔,這⾥裏僅列出具體做法:
添加自定義導出按鈕

<span class="btn btn-primary " style="float:left;margin-right:5px;" databind="click:exportExcelCustom">
	<i class="fa fa-file-excel-o" style="marginright:3px;">
	</i><@spring.message "2062.organizationaccessb.exportexcelcustom"/>
</span>

擴展 viewModel 對象並添加 exportExcelCustom 方法:

var viewModel = Hap.createGridViewModel("#grid", {
    exportExcelCustom: function () {
        var exportConfig = {};
        var columns = [];
        var index = 0;
        var grid = $("#grid").data("kendoGrid"); //獲取kendoGrid對象
        for (var i = 0; i < grid.columns.length; i++) { //遍歷所有字段
            if (grid.columns[i].field != null) {
                var columnInfo = {};
                columnInfo["name"] = grid.columns[i].field; //獲取字段name
                columnInfo["title"] = grid.columns[i].title; //獲取字段實際顯示標題
                columnInfo["width"] = grid.columns[i].width; //獲取字段顯示寬度
                var align = $('tbody').find('tr')[0].getElementsByTagName('td')
                    [i].style.textAlign; //獲取對其⽅方式
                if (align != null || align != '') {
                    columnInfo["align"] = align;
                }
                if (dataSource.options.schema.model.fields[grid.columns[i].field] != null) {
//獲取字段類型
                    columnInfo["type"] =
                        dataSource.options.schema.model.fields[grid.columns[i].field].type;
                }
                columns[index] = columnInfo; //將數據導⼊入columns中
                index++;
            }
        }
        exportConfig["columnsInfo"] = columns; //將columns數據導⼊入exportConfig中
        exportConfig["param"] = Hap.prepareQueryParameter(this.model.toJSON()); //獲取⽹網⻚頁限制條件
        exportConfig["fileName"] = "OrganizationAccess"; //設置⽂文件名
        var $inputImg = $('<input>').attr({
            name: "config", value:
                kendo.stringify(exportConfig)
        }); //將⻚頁⾯面信息傳到$inputImg中,定義input,並設置name和
        value屬性
        var
            $inputToken = $('<input>').attr({
                name: "${_csrf.parameterName}", value: "${_csrf.token}",
                type: "hidden"
            }); //傳⼊入token,以實現跨域訪問,定義input
        var $form = $("<form>"); //定義form
        $form.attr({ //設置form的target,method,action屬性
            target: '_self',
            method: 'post',
            action: '${base.contextPath}/xxfnd/organization/access/export/excel/custom'
        }).append($inputImg); //在form中添加$inputImg,添加input域
        $form.append($inputToken); //在form中添加$inputToken
        $form.id = 'smbForm'; //設置form的id
        $("#batchDiv").empty().append($form); //在batchDiv中添加該form
        $($form).submit(); //提交form
        $("#batchDiv").empty(); //置空batchDiv
    }
});

例子:

exportExcelCustom: function () {
    var exportConfig = {};
    var columns = [];
    var index = 0;
    var grid = $("#grid").data("kendoGrid"); //獲取kendoGrid對象
    for (var i = 0; i < grid.columns.length; i++) { //遍歷所有字段
        if (grid.columns[i].field != null) {
            var columnInfo = {};
            columnInfo["name"] = grid.columns[i].field; //獲取字段name
            columnInfo["title"] = grid.columns[i].title; //獲取字段實際顯示標題
            columnInfo["width"] = grid.columns[i].width; //獲取字段顯示寬度
            var align = $('tbody').find('tr')[0].getElementsByTagName('td')
                [i].style.textAlign; //獲取對其⽅方式
            if (align != null || align != '') {
                columnInfo["align"] = align;
            }
            if (dataSource.options.schema.model.fields[grid.columns[i].field] != null) {//獲取字段類型
                columnInfo["type"] = dataSource.options.schema.model.fields[grid.columns[i].field].type;
            }
            columns[index] = columnInfo; //將數據導⼊入columns中
            index++;
        }
    }
    exportConfig["columnsInfo"] = columns; //將columns數據導入exportConfig中
    exportConfig["param"] = Hap.prepareQueryParameter(this.model.toJSON()); //獲取網頁限制條件
    exportConfig["fileName"] = "OraOrgAccess"; //設置文件名
    var $inputImg = $('<input>').attr({name: "config", value: kendo.stringify(exportConfig)});
    //將⻚頁⾯面信息傳到$inputImg中,定義input,並設置name和value屬性
    var $inputToken = $('<input>').attr({name: "${_csrf.parameterName}", value: "${_csrf.token}", type: "hidden"});
    //傳入token,以實現跨域訪問,定義input
    var $form = $("<form>"); //定義form
    $form.attr({ //設置form的target,method,action屬性
        target: '_self',
        method: 'post',
        action: '${base.contextPath}/wht/ora/org/access/excel/custom'
    }).append($inputImg); //在form中添加$inputImg,添加input域
    $form.append($inputToken); //在form中添加$inputToken
    $form.id = 'smbForm'; //設置form的id
    $("#form-container").empty().append($form); //在batchDiv中添加該form
    $($form).submit(); //提交form
    $("#form-container").empty(); //置空batchDiv
}

在控制器中添加處理邏輯:
調⽤用excelService.exportAndDownloadExcel 服務⽅方法來完成 Excel 的導出。

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hand.hap.excel.dto.ColumnInfo;
import com.hand.hap.excel.dto.ExportConfig;
import com.hand.hap.excel.service.IExportService;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

 @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private IExportService excelService;

    //用於自定義導出
    @RequestMapping(value = "/wht/ora/org/access/excel/custom")
    public void exportExcelCustom(HttpServletRequest request, @RequestParam String config, HttpServletResponse httpServletResponse) throws IOException {
        IRequest requestContext = createRequestContext(request);
        JavaType type = objectMapper.getTypeFactory().constructParametrizedType(ExportConfig.class, ExportConfig.class, OraOrgAccess.class, ColumnInfo.class);
        ExportConfig<OraOrgAccess, ColumnInfo> exportConfig = objectMapper.readValue(config, type);
        excelService.exportAndDownloadExcel("wht.ora.mapper.OraOrgAccessMapper.selectOraOrgAccessByOrder", exportConfig, request, httpServletResponse, requestContext);
    }

4、自定義 Excel 導入

當 HAP 框架自帶的標準導入功能無法滿足要求時,我們可以利用框架已集成進來的 POI 開源組件庫來
自己解析 Office 文檔並實施導入過程。

1. 項目配置

編輯 src/main/resources/spring/applicationContext-beans.xml 文件,並添加以下內容:

<bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--setthemaxuploadsize100MB-->
        <property name="maxUploadSize">
            <value>104857600</value>
        </property>
        <property name="maxInMemorySize">
            <value>4096</value>
        </property>
 </bean>

2. 添加 jquery-form 庫依賴

將最新版的 jquery-form 庫⽂文件放置在 src/main/webapp/resources/js/jquery-form/jquery-form.js
jquery-form 庫官⽅方⽹網站: http://jquery.malsup.com/form/

3. 添加導入 Excel 的服務方法

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

private final static String excel2003L =".xls";    //2003- 版本的excel
private final static String excel2007U =".xlsx";   //2007+ 版本的excel

public ResponseData importExcel(InputStream is, String fileName) throws Exception {
        //用於返回操作的結果
        ResponseData rd = new ResponseData();
        List<List<Object>> list = new ArrayList<List<Object>>();
        // Create a new workbook
        Workbook workbook = null;
        //分割字符串,以.將文件擴展名截取出來賦值給fileType
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        //通過文件的擴展名選擇合適的文件解釋器將文件解釋成workbook
        if (excel2003L.equals(fileType)) {
            workbook = new HSSFWorkbook(is); //2003-
        } else if (excel2007U.equals(fileType)) {
            workbook = new XSSFWorkbook(is); //2007+
        } else {
            throw new Exception("解析的文件格式有誤!");
        }
        //創建文件的頁,行,列
        Sheet worksheet = null;
        Row row = null;
        Cell cell = null;
        //遍歷Excel中所有的sheet,逐頁解析
        //workbook.getNumberOfSheets()用於獲取文件的頁數
        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
            //獲取當前頁對象
            worksheet = workbook.getSheetAt(i);
            //如果頁爲空值,繼續下一頁的解析
            if (worksheet == null) {
                continue;
            }
            //遍歷當前sheet中的所有行
            //getFirstRowNum()獲取當前第一行的行號
            //worksheet.getLastRowNum()獲取最後一行的行號,
            for (int j = worksheet.getFirstRowNum(); j < worksheet.getLastRowNum() + 1; j++)
            {
                //獲取當前的行對象
                row = worksheet.getRow(j);
                // 跳過空行和標題行(第一行)
                if (row == null || row.getFirstCellNum() == j) {
                    continue;
                }
                //遍歷所有的列,創建li對象用於存放該行的值
                List<Object> li = new ArrayList<Object>();
                for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {
                    cell = row.getCell(y);
                    li.add(this.getCellValue(cell));
                }
                list.add(li);
            }
        }
        workbook.close();
        // 從第二行開始遍歷,第二行爲字段名稱
        // 將每行數據一條一條插入數據庫
        for (int i = 1; i < list.size(); i++) {
            List<Object> excelRow = list.get(i);
            OraOrgAccess dto = new OraOrgAccess();
            dto.setAccessName(excelRow.get(0).toString());
            dto.setDescription(excelRow.get(1).toString());
            dto.setOrgType(excelRow.get(2).toString());
            dto.setOrgId(Long.parseLong(excelRow.get(3).toString()));
            dto.setRoleId(1L);
            dto.setUserId(1L);
            oraOrgAccessMapper.insertSelective(dto);
        }
        //沒有發生異常,將ResponseData的Success屬性設置成true
        rd.setSuccess(true);
        //返回信息提示
        rd.setMessage("Import successfully!");
        return rd;
    }

    //對Cell的值進行格式化處理
    private Object getCellValue(Cell cell) {
        Object value = null;
        DecimalFormat df = new DecimalFormat("0");
        //格式化number String字符
        SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd");
        //日期格式化
        DecimalFormat df2 = new DecimalFormat("0.00");
        //格式化數字
        if (cell != null) {
            switch (cell.getCellType()) {
                case Cell.CELL_TYPE_STRING:
                    value = cell.getRichStringCellValue().getString();
                    break;
                case Cell.CELL_TYPE_NUMERIC:
                    if ("General".equals(cell.getCellStyle().getDataFormatString())) {
                        value = df.format(cell.getNumericCellValue());
                    } else if ("m/d/yy".equals(cell.getCellStyle().getDataFormatString())) {
                        value = sdf.format(cell.getDateCellValue());
                    } else {
                        value = df2.format(cell.getNumericCellValue());
                    }
                    break;
                case Cell.CELL_TYPE_BOOLEAN:
                    value = cell.getBooleanCellValue();
                    break;
                case Cell.CELL_TYPE_BLANK:
                    value = "";
                    break;
                default:
                    break;
            }
        } else {
            value = "";
        }
        return value;
    }

4. 在控制器器層添加 RESTful api 路徑和方法

//用於自定義導入

@RequestMapping(value = {"/wht/ora/org/access/excel/import/custom"}, method= {RequestMethod.POST})
    public ResponseData uploadExcel(HttpServletRequest request, Locale locale, String contextPath) throws Exception {
        //用於返回操作結果
        ResponseData rd = new ResponseData();
        //IRequest requestCtx = createRequestContext(request);
        //接收多文件
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        //通過前臺的設置ID截取json的upfile的值賦給多文件類型
        MultipartFile file = multipartRequest.getFile("upfile");
        if (file == null || file.isEmpty()) {
            rd.setSuccess(false);
            rd.setMessage("File is empty!");
            return rd;
        }
        InputStream in = file.getInputStream();
        //將文件的流和文件名傳入服務層
        return service.importExcel(in, file.getOriginalFilename());
    }

5. 前端增加庫引用

<script src="${base.contextPath}/resources/js/jquery-form/jquery-form.js"></script>

6. 前端頁面增加導入方法

function importExcel() {
        $('#formUpload').ajaxSubmit({
            dataType: 'json',
            success: function (data) {
                if (data.success) {
                    kendo.ui.showInfoDialog({
                        message: data.message
                    });
                } else {
                    kendo.ui.showErrorDialog({
                        message: data.message
                    });
                }
            }
        });
    }

7. 前端定義上傳 Excel 的表單

<form method="POST" enctype="multipart/form-data" id="formUpload"
          action="${base.contextPath}/wht/ora/org/access/excel/import/custom?${_csrf.parameterName}=${_csrf.token}">
        <div class="form-group pull-left">
            <div class="k-content">
                <!--<label class="control-label" style="margin-top: 2px">Attachment</label>-->
                <input type="file" id="upfile" name="upfile" style="display:none"
                       onchange="changeAgentContent()"/>
                <input style="width: 200px" value="" disabled id="inputFileAgent" datarole="maskedtextbox" type="text"
                       class="k-textbox"/>
                <input type="button" class="btn btn-primary"
                       onclick="document.getElementById('upfile').click()"
                       value='<@spring.message "OraOrgAccess.choosefile"/>'/>
                <script type="text/javascript">
                    function changeAgentContent() {
                        var value = document.getElementById("upfile").value;
                        var split = value.split("\\");
                        document.getElementById("inputFileAgent").value = split[split.length - 1]
                    }
                </script>
                <span class="btn btn-success" style="margin-left: 5px" onclick="importExcel()"
                      type="button"><i class="fa fa-arrow-circle-up" style="margin-right:3px;"></i><@spring.message "OraOrgAccess.importexcel"/></span>
            </div>
        </div>
    </form>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章