excel导入导出

excel导入导出的实现,纯前端实现,前后端配合实现

前后端配合实现

1.后端

1.所需依赖


            org.apache.poi
            poi
            3.16
        

        
            org.apache.poi
            poi-ooxml
            3.14
        

2.导出接口,下面使用到的userEventity 是写的测试实体类 简单的几个字段 id,name,age等等

@RequestMapping(value="/export",method=RequestMethod.POST)
	public void export(HttpServletResponse response){
		List users = service.search();
		
		HSSFWorkbook hb = new HSSFWorkbook();
		HSSFSheet sheet = hb.createSheet("获取excel测试表格");
		HSSFRow hr = null;// HSSFRow它的构造方法有三个,但每一个都是protected的,所以不能直接使用它的构造方法,而是用Sheet对象来创建行。 
		
//		先获取工作薄对象:
//		HSSFWorkbook wb = new HSSFWorkbook();
//		HSSFSheet sheet = wb.createSheet();
		HSSFCellStyle style = hb.createCellStyle();
//		一、设置背景色:
//		style.setFillForegroundColor((short) 13);// 设置背景色
//		style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
//		二、设置边框:
//		style.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框
//		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框
//		style.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框
//		style.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框
//		三、设置居中:
		style.setAlignment(HorizontalAlignment.CENTER); // 居中
//		四、设置字体:
		HSSFFont font = hb.createFont();
		font.setFontName("黑体");
		font.setFontHeightInPoints((short) 16);//设置字体大小
//		HSSFFont font2 = wb.createFont();
//		font2.setFontName("仿宋_GB2312");
//		font2.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//粗体显示
//		font2.setFontHeightInPoints((short) 12);
		style.setFont(font);//两种字体选择需要用到的字体格式
//		五、设置列宽:
//		sheet.setColumnWidth(0, 3766); //第一个参数代表列id(从0开始),第2个参数代表宽度值
//		六、设置自动换行:
//		setBorder.setWrapText(true);//设置自动换行
//		七、合并单元格:
//		Region region1 = new Region(0, (short) 0, 0, (short) 6);
//		参数1:行号 参数2:起始列号 参数3:行号 参数4:终止列号
//		sheet.addMergedRegion(region1);
//		八、加边框
//		HSSFCellStyle cellStyle= wookBook.createCellStyle();
//		cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
//		cellStyle.setBorderBottom(HSSFCellStyle.BorderBORDER_MEDIUM);
// 	    cellStyle.setBottomBorderColor(HSSFColor.BLACK.index);
//		cellStyle.setBorderLeft(HSSFCellStyle.BORDER_MEDIUM);
//		cellStyle.setLeftBorderColor(HSSFColor.BLACK.index);
//		cellStyle.setBorderRight(HSSFCellStyle.BORDER_MEDIUM);
//		cellStyle.setRightBorderColor(HSSFColor.BLACK.index);
//		cellStyle.setBorderTop(HSSFCellStyle.BORDER_MEDIUM);
//		cellStyle.setTopBorderColor(HSSFColor.BLACK.index);
//		hr = sheet.createRow(0);
//		hr.setHeight((short) (26.25 * 20));
//		hr.createCell(0).setCellValue("用户信息列表");//为第一行单元格设值
		  /*为标题设计空间
	      * firstRow从第1行开始
	      * lastRow从第0行结束
	      *
	      *从第1个单元格开始
	      * 从第3个单元格结束
	      */
//		CellRangeAddress rowRegion = new CellRangeAddress(0, 0, 0, 2); // 跨行跨列
//	    sheet.addMergedRegion(rowRegion);
	    
	    hr = sheet.createRow(0); // 创建第一行对象
	    hr.setHeight((short) (28 * 20));//设置行高
	    sheet.setColumnWidth(1, 10*256);//设置列宽
	    hr.setRowStyle(style);
	    hr.createCell(0).setCellValue("姓名");//为第一个单元格设值
	    hr.createCell(1).setCellValue("年龄");//为第二个单元格设值
	    hr.createCell(2).setCellValue("性别");//为第三个单元格设值
	    hr.createCell(3).setCellValue("学历");//为第三个单元格设值
	    for (int i = 0; i < users.size(); i++) {
	         hr = sheet.createRow(i + 1);// 创建第i+1对象
	         hr.setHeight((short) (26 * 20));//设置行高
	         UserEntity user = users.get(i);
	         hr.createCell(0).setCellValue(user.getUsername());
	         hr.createCell(1).setCellValue(user.getAge());
	         hr.createCell(2).setCellValue(user.getSex());
	         hr.createCell(3).setCellValue(user.getEdu());
	      }
	    sheet.setDefaultRowHeight((short) (16.5 * 20));// 默认高度
//	  //列宽自适应
//	      for (int i = 0; i <= 13; i++) {
//	         sheet.autoSizeColumn(i);
//	      }
	      
	      response.setContentType("application/vnd.ms-excel;charset=utf-8");
	      response.setHeader("filename", "user.xlsx");//Excel文件名称,前端下载使用这个文件名
	      OutputStream os;
		try {
			os = response.getOutputStream();
			hb.write(os);
			os.flush();
			os.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

3,导入

@RequestMapping(value="/import",method=RequestMethod.POST)
	public String excelImport(MultipartFile file) throws Exception{
		String fileName = file.getOriginalFilename();
		return service.importExcel(fileName,file);
	}
@Override
	public String importExcel(String fileName, MultipartFile file) throws Exception {
		System.out.println("fileNamefffffffffffffff::::::"+fileName);
		List userList = new ArrayList<>();
	      if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
	         return "上传文件格式不正确";
	      }
	      boolean isExcel2003 = true;
	      if (fileName.matches("^.+\\.(?i)(xlsx)$")) {// 判断是否是Excel2003版
	         isExcel2003 = false;
	      }
	      InputStream is;
	      Workbook wb = null;
		try {
			is = file.getInputStream();
			if (isExcel2003) {
		         wb = new HSSFWorkbook(is);
		      } else {
		         wb = new XSSFWorkbook(is);
		      }
		} catch (IOException e) {
			e.printStackTrace();
		}
		  // getSheetAt()获取给定索引处的Sheet对象。
	      Sheet sheet = wb.getSheetAt(0);
	      UserEntity user;
	      if(sheet!=null){
	    	  for (int r = 1; r <= sheet.getLastRowNum(); r++) {//r = 2 表示从第三行开始循环 如果你的第三行开始是数据
	    	         Row row = sheet.getRow(r);//通过sheet表单对象得到 行对象
	    	         if (row == null){
	    	            continue;
	    	         }
	    	         user = new UserEntity();

	    	         if( row.getCell(0).getCellType() !=1){//循环时,得到每一行的单元格进行判断
	    	            return "导入失败(第"+(r+1)+"行,请设为文本格式)";
	    	         }
	    	         //得到每一行第一个单元格的值
	    	         String username = row.getCell(0).getStringCellValue();
	    	         if(username == null || username.isEmpty()){//判断是否为空
	    	            return "导入失败(第"+(r+1)+"行,姓名未填写)";
	    	         }
	    	         //得到每一行的 第二个单元格的值
	    	         String age = "";
	    	         if(row.getCell(1).getCellType() == HSSFCell.CELL_TYPE_NUMERIC){
	    	        	 age = String.valueOf(row.getCell(1).getNumericCellValue());
	    	        	 age = age.substring(0,age.lastIndexOf("."));
	    	        	 if(age.isEmpty() || age == null){
		    	             return "导入失败(第"+(r+1)+"行,年龄未填写)";
		    	          }
	    	         }else{
	    	        	 age = row.getCell(1).getStringCellValue();
	    	         }
	    	         
	    	         //得到每一行的 第三个单元格的值
	    	         String sex = "";
	    	         // 如果得到的值类型为数字
	    	         if(row.getCell(2).getCellType() == HSSFCell.CELL_TYPE_NUMERIC){
	    	        	 // 因为getNumericCellValue()方法得到的数字是double类型,比如值是2,得到的就是2.0;
	    	        	 sex = String.valueOf(row.getCell(2).getNumericCellValue());
	    	        	 // 转为字符串然后拆分截取
	    	        	 sex = sex.substring(0,sex.lastIndexOf("."));
	    	        	 if(sex==null || sex.isEmpty()){
		    	             return "导入失败(第"+(r+1)+"行,年龄未填写)";
		    	          }
	    	         }else {// 否则直接获取文本值
	    	        	 sex = row.getCell(2).getStringCellValue();
					}
	    	         
	    	         //得到每一行的 第四个单元格的值
	    	         String edu = "";
	    	         try {
	    	        	 edu = row.getCell(3).getStringCellValue();
					} catch (Exception e) {
//						return "导入失败(第"+(r+1)+"行,学历未填写)";
						throw new Exception("导入失败(第"+(r+1)+"行,学历未填写)");
					}
	    	         user.setId(UUID.randomUUID().toString().replaceAll("-", "").toUpperCase());
	    	         user.setUsername(username);
	    	         user.setSex(sex);
	    	         user.setAge(age);
	    	         user.setEdu(edu);
	    	         userList.add(user);
	    	  }
	    	  System.out.println(userList);
	    	  for (UserEntity userResord : userList) {
	    	         String name = userResord.getUsername();
	    	         int cnt = mapper.selectByName(name);
	    	         if (cnt == 0) {
	    	        	 mapper.add(userResord);
//	    	            System.out.println(" 插入 "+userResord);
	    	         } else {
	    	            mapper.update(userResord);
//	    	            System.out.println(" 更新 "+userResord);
	    	         }
	    	      }
	    	
	      }
		return "导入成功";

	}

2.前端

1.导出请求,testapi是在vue项目中config/index.js中配置的跨域访问头部

// 导出报表
export const exportReport = params => { return axios.post(`testapi/excel/export`,params,{responseType:'blob'});};

2.请求

import { exportReport} from '../../api/api.js'
exportReport().then(res => {
            this.isShow = false;
            let blob = new Blob([res.data], {type: 'application/vnd.ms-excel'});
            let fileUrl = URL.createObjectURL(blob);
            let a = document.createElement("a");
            a.setAttribute("href", fileUrl);
            a.setAttribute("download", res.headers.filename);
            a.click();
            a.remove();
          })

3.导入excel

// 上传
export const postFileUpload = params =>{return axios.post('/testapi/excel/import',params)};
  import {postFileUpload} from '../../api/api.js'

uploadFile(e){
let formData = new FormData();
let list=e.target.files;
for(let i=0;i{
  console.log(res)
})
}

---------------------------------------前后端交互完成excel文件的导入导出完成-----------------------------------

前端单独实现

1.导出,把json数据导出excel的两种写法

界面展示如下

excel导入导出_第1张图片

选择需要导出的列的界面 

excel导入导出_第2张图片

 

第一种 直接导出,tableList 是在后端请求的json数据展示页面是个表格 ,isChooseHead* 表示上图中复选框选择的结果

exportEvent2() {
        // 列标题,逗号隔开,每一个逗号就是隔开一个单元格
        let str = ``;
        if(this.isChooseHead1) str+=`项目,`;
        if(this.isChooseHead2) str+=`区域,`;
        if(this.isChooseHead3) str+=`房号,`;
        if(this.isChooseHead4) str+=`面积,`;
        if(this.isChooseHead5) str+=`网格编号,`;
        str = str.substring(0,str.lastIndexOf(',')) + `\n`;
        // 增加\t为了不让表格显示科学计数法或者其他格式
        let jsonData = [];
        this.tableList && this.tableList.map(v=>{
          let obj = {};
          if(this.isChooseHead1)obj.manageName = v.manageName || '';
          if(this.isChooseHead2)obj.areaName = v.areaName || '';
          if(this.isChooseHead3)obj.roomId = v.roomId || '';
          if(this.isChooseHead4)obj.acreage = v.acreage || '';
          if(this.isChooseHead5)obj.gridId = v.gridId || '';
          jsonData.push(obj);
        });
        for(let i = 0 ; i < jsonData.length ; i++ ){
          for(const key in jsonData[i]){
            // str+=`${jsonData[i][key] + '\t'},`;
            str+=`${jsonData[i][key]},`;
          }
          str+='\n';
        }
        // encodeURIComponent解决中文乱码
        const uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(str);
        // 通过创建a标签实现
        const link = document.createElement("a");
        link.href = uri;
        // 对下载的文件命名
        link.download =  "json数据测试.xlsx";
        link.click();
        link.remove();
        this.isShow = false;
      },

第二种导出 需要借用xlsx.core.min.js插件,文档地址,文件在dist目录下

https://github.com/SheetJS/sheetjs

exportEvent() {
        let json = [];
        this.tableList && this.tableList.map(v=>{
          let obj = {};
          if(this.isChooseHead1)obj['项目'] = v.manageName || '';
          if(this.isChooseHead2)obj['区域'] = v.areaName || '';
          if(this.isChooseHead3)obj["房号"] = v.roomId || '';
          if(this.isChooseHead4)obj["面积"] = v.acreage || '';
          if(this.isChooseHead5)obj["网格编号"] = v.gridId || '';
          json.push(obj);
        });
        console.log(json);
        let ws =  XLSX.utils.json_to_sheet(json);
        /* 新建空workbook,然后加入worksheet */
        let wb = XLSX.utils.book_new();
        XLSX.utils.book_append_sheet(wb, ws, "room");
        /* 生成xlsx文件 */
        XLSX.writeFile(wb, "测试.csv");
        this.isShow = false;
      },

2.导入,把excel文件转为json数据

同样需要用到xlsx.core.min.js

importEvent(e){
        let file = e.target.files;
        let fileNameArr = file[0].name.split('.')||[];
        let fileType = fileNameArr[fileNameArr.length - 1] || '';
         if(fileType === 'xls' || fileType === 'xlsx'||fileType === 'XLS' || fileType === 'XLSX'){
          let reader = new FileReader();
          reader.onload = function (el) {
            let data = el.target.result;
            let wb = XLSX.read(data, {type: 'binary'});
            let a = wb.Sheets[wb.SheetNames[0]];
            // console.log(a);
            for(let k in a){
              for(let k1 in a[k]){
                if(a[k][k1] === '项目')a[k][k1] = 'manageName';
                if(a[k][k1] === '区域')a[k][k1] = 'areaName';
                if(a[k][k1] === '房号')a[k][k1] = 'roomId';
                if(a[k][k1] === '面积')a[k][k1] = 'acreage';
                if(a[k][k1] === '网格编号')a[k][k1] = 'gridId';
              }
            }
            let arr = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
            console.log(arr);
          };
          reader.readAsBinaryString(file[0]);
        }else {
          this.$message({message:"请上传.xlsx或.xls文件",type:'error'})
        }

      },

你可能感兴趣的:(vue)