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