基本导入导出的文档入口: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>