目前java项目导入Excel文件,处理少量数据时使用Workbook解析没有问题,但在遇到海量数据时就会崩溃,查阅资料结合别人的代码自己也写了一个实例。
先看结论再看代码:
1.优点:灵活,如有多个不同的Excel表,可以写多个ExcelXXXReader,例如我有三个表,Coupon,Qa,Order,那我就对应ExcelCouponReader,ExcelQaReader,ExcelOrderReader,再新增类型表格,只需要对应新增Reader就可以了。
2 缺点:解析速度慢,对比别人写的工具类,100W,1000W的数据,只需要10S,20S,抱歉我20个字段,ThinkPad,20W的数据需要80s。
3 想省事的话,第一第二段代码直接粘贴复制,将其中的实体类替换成自己的就可以了。
代码部分:工具分为两个部分,一个是对读取Excel表格,另一个是将Excel中的字段一一解析到对应的实体类中。
import org.apache.log4j.Logger;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* package
* Description:用于解析大数据量的EXCEL文件工具类,可以解析少量的emoji表情的,如有昵称,建议将该字段删除
* Date:
* Author:
**/
public abstract class XxlsAbstractReader extends DefaultHandler {
private static final Logger logger = Logger.getLogger(XxlsAbstractReader.class);
private SharedStringsTable sst;
private String lastContents;
private boolean nextIsString;
private int sheetIndex = -1;
private List<Object> rowlist = new ArrayList<Object>();
private int curRow = 0; // 当前行
private int curCol = 0; // 当前列索引
private int preCol = 0; // 上一列列索引
private int titleRow = 0; // 标题行,一般情况下为0
private int rowsize = 0; // 列数
// excel记录行操作方法,以sheet索引,行索引和行元素列表为参数,对sheet的一行元素进行操作,元素为String类型
public abstract void optRows(int sheetIndex, int curRow, List<Object> rowlist) throws SQLException;
// 只遍历一个sheet,其中sheetId为要遍历的sheet索引,从1开始,1-3
/**
* @param filename
* @param sheetId sheetId为要遍历的sheet索引,从1开始,1-3
* @throws Exception
*/
public void processOneSheet(String filename, int sheetId) throws Exception {
OPCPackage pkg = OPCPackage.open(filename);
XSSFReader r = new XSSFReader(pkg);
SharedStringsTable sst = r.getSharedStringsTable();
XMLReader parser = fetchSheetParser(sst);
// rId2 found by processing the Workbook
// 根据 rId# 或 rSheet# 查找sheet
InputStream sheet2 = r.getSheet("rId" + sheetId);
sheetIndex++;
InputSource sheetSource = new InputSource(sheet2);
parser.parse(sheetSource);
sheet2.close();
}
/**
* 遍历 excel 文件
*/
public void process(String filename) throws Exception {
OPCPackage pkg = OPCPackage.open(filename);
XSSFReader r = new XSSFReader(pkg);
SharedStringsTable sst = r.getSharedStringsTable();
XMLReader parser = fetchSheetParser(sst);
Iterator<InputStream> sheets = r.getSheetsData();
while (sheets.hasNext()) {
curRow = 0;
sheetIndex++;
InputStream sheet = sheets.next();
InputSource sheetSource = new InputSource(sheet);
parser.parse(sheetSource);
sheet.close();
}
}
/**
* 遍历 excel 文件
*/
public void process(InputStream in) throws Exception {
OPCPackage pkg = OPCPackage.open(in);
XSSFReader r = new XSSFReader(pkg);
SharedStringsTable sst = r.getSharedStringsTable();
XMLReader parser = fetchSheetParser(sst);
Iterator<InputStream> sheets = r.getSheetsData();
while (sheets.hasNext()) {
curRow = 0;
sheetIndex++;
InputStream sheet = sheets.next();
InputSource sheetSource = new InputSource(sheet);
parser.parse(sheetSource);
sheet.close();
}
}
public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException {
XMLReader parser = XMLReaderFactory.createXMLReader();
// .createXMLReader("org.apache.xerces.parsers.SAXParser");
this.sst = sst;
parser.setContentHandler(this);
return parser;
}
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
// c => 单元格
if ("c".equals(name)) {
// 如果下一个元素是 SST 的索引,则将nextIsString标记为true
String cellType = attributes.getValue("t");
String rowStr = attributes.getValue("r");
curCol = this.getRowIndex(rowStr);
if (cellType != null && "s".equals(cellType)) {
nextIsString = true;
} else {
nextIsString = false;
}
}
// 置空
lastContents = "";
}
public void endElement(String uri, String localName, String name) throws SAXException {
// 根据SST的索引值的到单元格的真正要存储的字符串
// 这时characters()方法可能会被调用多次
if (nextIsString) {
try {
int idx = Integer.parseInt(lastContents);
lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
} catch (Exception e) {
}
}
// v => 单元格的值,如果单元格是字符串则v标签的值为该字符串在SST中的索引
// 将单元格内容加入rowlist中,在这之前先去掉字符串前后的空白符
if ("v".equals(name)) {
String value = lastContents.trim();
value = "".equals(value) ? " " : value;
int cols = curCol - preCol;
if (cols > 1) {
for (int i = 0; i < cols - 1; i++) {
rowlist.add(preCol, "");
}
}
preCol = curCol;
rowlist.add(curCol - 1, value);
} else {
// 如果标签名称为 row ,这说明已到行尾,调用 optRows() 方法
if ("row".equals(name)) {
int tmpCols = rowlist.size();
if (tmpCols > 0) {
if (curRow > this.titleRow && tmpCols < this.rowsize) {
for (int i = 0; i < this.rowsize - tmpCols; i++) {
rowlist.add(rowlist.size(), "");
}
}
try {
optRows(sheetIndex, curRow, rowlist);
} catch (SQLException e) {
logger.error("endElement error", e);
}
} else {// 跳过空白行
logger.info("jump blank row ,curRow:" + (curRow + 1));
}
if (curRow == this.titleRow) {
this.rowsize = rowlist.size();
if (this.rowsize == 0) {
throw new RuntimeException("excel 未被编辑或者内容为空");
}
}
rowlist.clear();
curRow++;
curCol = 0;
preCol = 0;
}
}
}
public void characters(char[] ch, int start, int length) throws SAXException {
// 得到单元格内容的值
lastContents += new String(ch, start, length);
}
// 得到列索引,每一列c元素的r属性构成为字母加数字的形式,字母组合为列索引,数字组合为行索引,
// 如AB45,表示为第(A-A+1)*26+(B-A+1)*26列,45行
public int getRowIndex(String rowStr) {
rowStr = rowStr.replaceAll("[^A-Z]", "");
byte[] rowAbc = rowStr.getBytes();
int len = rowAbc.length;
float num = 0;
for (int i = 0; i < len; i++) {
num += (rowAbc[i] - 'A' + 1) * Math.pow(26, len - i - 1);
}
return (int) num;
}
public int getTitleRow() {
return titleRow;
}
public void setTitleRow(int titleRow) {
this.titleRow = titleRow;
}
public int getSheetIndex() {
return sheetIndex;
}
}
package com.bootdo.witdbct.operateVisu.importData;
import com.bootdo.common.config.ApplicationContextRegister;
import com.bootdo.common.utils.ShiroUtils;
import com.bootdo.witdbct.operateVisu.dao.DbctRPoperMapper;
import com.bootdo.witdbct.operateVisu.domain.DbctRPoper;
import com.bootdo.witdbct.system.domain.UserDO;
import com.yd.common.runtime.CIPRuntime;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @program: bootdo
* @description: 使用工具类对EXCEL文件进行解析并映射
* @author: WangChen
* @create: 2019-03-06 09:22
**/
public class ExcelReader extends XxlsAbstractReader {
/*@Autowired
private DbctRPoperMapper mapper;*/
private static ExcelReader excelRedder;
DbctRPoperMapper poperMapper = ApplicationContextRegister.getBean(DbctRPoperMapper.class);
/* @PostConstruct
public void init() {
excelRedder = this;
excelRedder.mapper = this.mapper;
}*/
/*List<DbctRPoper> poperL = getPoperL();
Map<String, String> dbctMaps = dbctMap(); */
List<Map<String, Object>> poperL = poperMapper.searchPoper();
List<Map<String, Object>> zzList = poperMapper.queryZZ();
List<String> dbctTee =dbctMap(poperL);
List<String> dbctList = dbctMap(zzList);
//private List<Map<String,Object>> voList = new ArrayList<>();
private List<DbctRPoper> voList = new ArrayList<>();
private List<String> curRowList = new ArrayList<>();
public ExcelReader() {
}
@Override
public void optRows(int sheetIndex, int curRow, List<Object> rowlist) throws SQLException {
if (curRow == 0) {
return;
}
int sheet = sheetIndex+1;
DbctRPoper poper = new DbctRPoper();
UserDO user = ShiroUtils.getUser();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_MONTH, 1);
String nextDay = sf.format(c.getTime())+" 00:00:00";//次日
poper.setDbct(Integer.parseInt((String)rowlist.get(0)));
poper.setDbctName((String)rowlist.get(1));
poper.setSte_par(new BigDecimal((String)rowlist.get(2)));
poper.setSor_par(new BigDecimal((String)rowlist.get(3)));
poper.setLoading_p_end1(new BigDecimal((String)rowlist.get(4)));
poper.setLoading_p_color1(changeColorEnFromZh(rowlist.get(5)));
poper.setLoading_p_end2(new BigDecimal((String)rowlist.get(6)));
poper.setLoading_p_color2(changeColorEnFromZh(rowlist.get(7)));
poper.setLoading_p_end3(new BigDecimal((String)rowlist.get(8)));
poper.setLoading_p_color3(changeColorEnFromZh(rowlist.get(9)));
poper.setUnload_ot1(new BigDecimal((String)rowlist.get(10)));
poper.setUnload_ot_color1(changeColorEnFromZh(rowlist.get(11)));
poper.setUnload_ot2(new BigDecimal((String)rowlist.get(12)));
poper.setUnload_ot_color2(changeColorEnFromZh(rowlist.get(13)));
poper.setStock_warning(new BigDecimal((String)rowlist.get(14)));
poper.setStock_warning_color(changeColorEnFromZh(rowlist.get(15)));
poper.setStock_full(new BigDecimal((String)rowlist.get(16)));
poper.setStock_full_color(changeColorEnFromZh(rowlist.get(17)));
poper.setTake_effect_time(nextDay);
if(StringUtils.isBlank(poper.getDbct().toString())){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据分拨编码为空!");
}
if(dbctTee.contains(poper.getDbct().toString())){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据再数据库中已存在!");
}
if(!dbctList.contains(poper.getDbct().toString())){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据分拨编码不存在!");
}
if(StringUtils.isBlank((String)rowlist.get(2))){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装卸工目标能效为空!");
}
if(StringUtils.isBlank((String)rowlist.get(3))){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据分拣工目标能效为空!");
}
if(StringUtils.isBlank((String)rowlist.get(4))){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点1为空!");
}else if( Integer.parseInt((String)rowlist.get(4)) < 0){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点1数据小于0!");
}
if(StringUtils.isBlank((String)rowlist.get(5))){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点1显示颜色为空!");
}
if(StringUtils.isBlank((String)rowlist.get(6))){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点2为空!");
}else if( Integer.parseInt((String)rowlist.get(6)) < 0){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点2数据小于0!");
}
if(StringUtils.isBlank((String)rowlist.get(7))){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点2显示颜色为空!");
}
if(StringUtils.isBlank((String)rowlist.get(8))){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点3为空!");
}else if( Integer.parseInt((String)rowlist.get(8)) < 0){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点3数据小于0!");
}
if(StringUtils.isBlank((String)rowlist.get(9))){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装车离时效截止点3显示颜色为空!");
}
if(StringUtils.isBlank((String)rowlist.get(10))){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据卸车超时1为空!");
}else if( Integer.parseInt((String)rowlist.get(10)) < 0){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据卸车超时1数据小于0!");
}
if(StringUtils.isBlank((String)rowlist.get(11))){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据卸车超时1显示颜色为空!");
}
if(StringUtils.isBlank((String)rowlist.get(12))){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据卸车超时2为空!");
}else if( Integer.parseInt((String)rowlist.get(12)) < 0){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据卸车超时2数据小于0!");
}
if(StringUtils.isBlank((String)rowlist.get(13))){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据卸车超时2显示颜色为空!");
}
if(StringUtils.isBlank((String)rowlist.get(14))){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据库存预警为空!");
}else if( Integer.parseInt((String)rowlist.get(14)) < 0 || Integer.parseInt((String)rowlist.get(14)) > 100){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据库存预警数据小于0!");
}
if(StringUtils.isBlank((String)rowlist.get(15))){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据库存预警显示颜色为空!");
}
if(StringUtils.isBlank((String)rowlist.get(16))){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据库存爆仓为空!");
}else if( Integer.parseInt((String)rowlist.get(16)) < 0 || Integer.parseInt((String)rowlist.get(14)) > 100){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据库存爆仓数据小于0!");
}
if(StringUtils.isBlank((String)rowlist.get(17))){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据库存爆仓显示颜色为空!");
}
/*if(poperL.contains(poper)){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据在数据库中已存在!");
}
if(!StringUtils.equals(poper.getDbctName(),dbctMaps.get(poper.getDbct().toString()))){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据分拨名称不匹配!");
}
if(StringUtils.equals(poper.getStevedore().toString(),"")||StringUtils.equals(poper.getStevedore().toString(),null)){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据装卸工为空!");
}
if(StringUtils.equals(poper.getPalletizer().toString(),"")||StringUtils.equals(poper.getPalletizer().toString(),null)){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据分拣工为空!");
}*/
poper.setEntry_man(user.getUserName());
poper.setEntry_man_id(user.getUserId());
poper.setImStatus("1");
if(voList.contains(poper)){
curRowList.add("sheet"+sheet+":EXCEL第"+curRow+"行数据重复!");
}
voList.add(poper);
//voList.add(poper);
}
public List<DbctRPoper> getExcelCouponList() {
return voList;
}
public List<String> getExcelcurRowList() {
return curRowList;
}
/**
* 日期类型字段会被解析成1900至今的毫秒数,自己写了一个工具,将毫秒数转换为日期,小时和分钟会丢失精度
* 此方法可自己重写!!!精度不够
* @param dataString
* @return
*/
public static String numToString(String dataString) {
if ("" != dataString && null != dataString) {
String str = null;
if (!dataString.contains(".")) {
Calendar calendar = new GregorianCalendar(1900,0,-1);
Date d1 = calendar.getTime();
Date d2 = DateUtils.addDays(d1,Integer.valueOf(dataString));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
str = sdf.format(d2);
}else {
String string = dataString.substring(0,dataString.lastIndexOf("."));
Calendar calendar = new GregorianCalendar(1900,0,-1);
Date d1 = calendar.getTime();
Date d2 = DateUtils.addDays(d1,Integer.valueOf(string));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
str = sdf.format(d2);
}
return str;
}
return "";
}
/**
* 将分拨数据组成Map,以便验证使用
* @return
*/
private List<String> dbctMap(List<Map<String, Object>> zzList){
List<String> list = new ArrayList<>();
for (Map<String, Object> map : zzList) {
list.add(String.valueOf(map.get("bm")));
}
return list;
}
/*private List<Map<String,Object>> getPoperL(){
DbctRPoperMapper poperMapper = ApplicationContextRegister.getBean(DbctRPoperMapper.class);
List<Map<String,Object>> dbctRPopers = poperMapper.searchPoper();
return dbctRPopers;
}*/
/**
* 显示颜色中英文转换
* @param color
* @return
*/
private String changeColorEnFromZh(Object color){
String col = "";
String str = (String)color;
if(StringUtils.equals(str,"红色")){
col = "red";
}
if(StringUtils.equals(str,"黄色")){
col = "yellow";
}
if(StringUtils.equals(str,"绿色")){
col = "green";
}
return col;
}
}
使用方式:
public static void main(String[] args) {
MultipartFile[] file;//此处为前台上传的多个文件,也可改为单个文件处理
try {
for(MultipartFile multipartFile : file){
String fileName = multipartFile.getOriginalFilename();
InputStream inputStream = multipartFile.getInputStream();
ExcelReader excelReader = new ExcelReader();
excelReader.process(inputStream);
//解析到List,准备验证保存
List<Map<String,Object>> excelCouponList = excelReader.getExcelCouponList();
if(excelCouponList.size() > 100000){
msg.setSuccess(false);
msg.setMessage("导入数据不能超过十万条!");
return msg;
}
int code = service.insertAll(excelCouponList);
if(code > 0){
msg.setSuccess(true);
msg.setMessage("文件导入成功!");
}else{
msg.setSuccess(false);
msg.setMessage("文件导入失败!");
}
}
} catch (Exception e) {
msg.setSuccess(false);
msg.setMessage("数据格式错误!");
}
}
项目中具体使用(前台):
js:
$(function (){
//0.初始化fileinput
var oFileInput = new FileInput();
oFileInput.Init("txt_file", ctx+"oper/importFile");
});
var FileInput = function () {
var oFile = new Object();
//初始化fileinput控件(第一次初始化)
oFile.Init = function(ctrlName, uploadUrl) {
var control = $('#' + ctrlName);
//初始化上传控件的样式
control.fileinput({
language: 'zh', //设置语言
uploadUrl: uploadUrl, //上传的地址
allowedFileExtensions:["xls", "xlsx"],//接收的文件后缀
showUpload: true, //是否显示上传按钮
showCaption: false,//是否显示标题
//showPreview:true,
browseClass: "btn btn-primary", //按钮样式
//dropZoneEnabled: false,//是否显示拖拽区域
//minImageWidth: 50, //图片的最小宽度
//minImageHeight: 50,//图片的最小高度
//maxImageWidth: 1000,//图片的最大宽度
//maxImageHeight: 1000,//图片的最大高度
//maxFileSize: 0,//单位为kb,如果为0表示不限制文件大小
//minFileCount: 0,
maxFileCount: 10, //表示允许同时上传的最大文件个数
enctype: 'multipart/form-data',
validateInitialCount:true,
previewFileType:["xls", "xlsx"],
previewFileIconSettings: {
'docx': '<i ass="fa fa-file-word-o text-primary"></i>',
'xlsx': '<i class="fa fa-file-excel-o text-success"></i>',
'xls': '<i class="fa fa-file-excel-o text-success"></i>',
'pptx': '<i class="fa fa-file-powerpoint-o text-danger"></i>',
'jpg': '<i class="fa fa-file-photo-o text-warning"></i>',
'pdf': '<i class="fa fa-file-archive-o text-muted"></i>',
'zip': '<i class="fa fa-file-archive-o text-muted"></i>',
},
msgFilesTooMany: "选择上传的文件数量({n}) 超过允许的最大数值{m}!",
});
//导入文件上传完成之后的事件
$("#txt_file").on("fileuploaded", function (event, data, previewId, index) {
//$("#import").modal("hide");
//console.log(data);
if(data.response.success == true){
//alert(data.files[index].name + "上传成功!");
//layer.msg(data.files[index].name + "上传成功!", {icon: 6});
var datasss = "";
for(var i = 0;i<data.files.length;i++){
datasss+=data.files[i].name;
}
swal({title: "成功", text: datasss + "上传成功!", type: "success"});
//关闭
// $(".close").click();
}else{
//alert(data.files[index].name + "上传失败!" + data.response.message);
//layer.msg(data.files[index].name + "上传失败!" + data.response.message, {icon: 5});
var tishi = data.files[index].name + "上传失败!";
//$(tishi).appendTo($("#tishi"));
var resData = data.response.message;
var result = resData.text;
var arr = [];
for(var i = 0;i<result.length;i++){
arr.push('<p>'+result[i]+'<p/>');
}
var str = arr.join('');
$(str).appendTo($('#importInfoBody'));
$("#importInfo").modal();
//重置
$("#txt_file").fileinput("clear");
$("#txt_file").fileinput("reset");
$('#txt_file').fileinput('refresh');
$('#txt_file').fileinput('enable');
}
});
}
return oFile;
};
html:
<!-- 模态框(Modal) -->
<!--导入数据操作层-->
<form>
<div class="modal fade" id="import" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" style="z-index:9992;">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">请选择Excel文件</h4>
</div>
<div class="modal-body">
<a href="#" class="form-control" style="border:none;color: blue;text-decoration:underline;" onclick="downloadTemplate()">下载导入模板</a>
<input type="file" name="txt_file" id="txt_file" multiple class="file-loading" />
</div></div>
</div>
</div>
</form>
<!--导入消息提示框-->
<div class="modal fade" id="importInfo">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3 id="tishi">提示 </h3>
</div>
<div class="modal-body" id="importInfoBody">
</div>
<div class="modal-footer">
<button class="btn btn-info" data-dismiss="modal">关闭</button>
</div>
</div>
</div>
</div>