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