记录一下项目中下载模板和poi导出excel功能开发过程

1.需求场景:项目中联系人模块需要导入导出excel和下载excel模板功能
在这里插入图片描述
此处只记录 下载模板和导出excel功能
2.流程:前台用超链接形式 点击后发送get请求 然后后台实现功能。
3.代码:项目使用的是Idea+springboot+kotlin
3.1 controller:

@Value("\${download.template.xls.sms_link}")
    private var smsLinkTemplate: String = ""

	@GetMapping("export/{id}")
    fun exportFile(@PathVariable("id") id: Int, resp: HttpServletResponse) {
        when (id) {
            1 -> callCenterService.exportOutLinker(resp, "outLinker.xls")
        }
    }

    @GetMapping("download/{id}")
    fun downloadFile(@PathVariable("id") id: Int, resp: HttpServletResponse) {
        when (id) {
            1 -> callCenterService.downLoadExcel(resp, smsLinkTemplate)
        }
    }

3.2 service:

//poi导出excel
    fun exportOutLinker(resp: HttpServletResponse, excelName: String) {
        val workbook = HSSFWorkbook()
        val sheet = workbook.createSheet("通讯录")
        val linkerList = ****//查表
        var rowNum = 1

        val headers = arrayOf("姓名", "手机号", "标签", "备注")
        val row = sheet.createRow(0)
        headers.indices.map { i ->
            val cell = row.createCell(i)
            val text = HSSFRichTextString(headers[i])
            cell.setCellValue(text)
        }
        linkerList.map { link ->
            val row = sheet.createRow(rowNum)
            row.createCell(0).setCellValue(link.name)
            row.createCell(1).setCellValue(link.phone)
            .....//其他字段
            rowNum++
        }
        resp.setContentType("application/octet-stream")//告诉浏览器输出内容为流
        resp.setHeader("Content-disposition", "attachment;filename=$excelName")
        try {
            val out = resp.outputStream
            workbook.write(out)
            out.flush()
            out.close()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    //下载excel模板
    fun downLoadExcel(resp: HttpServletResponse, excelName: String) {
        try {
            val file = ResourceUtils.getFile("classpath:temp/$excelName")
            if (file.exists()) {
                val inStream = FileInputStream(file)
                resp.setContentType("multipart/form-data")//自动判断下载文件类型
                resp.setHeader("Content-Disposition", "attachment;filename=${URLEncoder.encode(excelName, "UTF-8")}")
                val out = resp.outputStream
                var b = 0
                val buffer = ByteArray(100000)
                while (b != -1) {
                    b = inStream.read(buffer);
                    if (b != -1) out.write(buffer, 0, b)
                }
                inStream.close();
                out.flush();
                out.close();
            }
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

3.3 application.properties

# project download template file name
download.template.xls.sms_link=sms_link_template.xls

3.4 文件位置
在这里插入图片描述

3.5 前台使用的是超链接,所以提供请求路径给前台
前台:
在这里插入图片描述
controller:

@GetMapping("address/{id}")
    fun address(@PathVariable("id") id: Int, req: HttpServletRequest): Map<String, Any> {
        val result = HashMap<String, Any>()
        var url = ""
        val addr = "${req.scheme}://${req.serverName}:${req.serverPort}${req.contextPath}"
        when (id) {
            1 -> url = "$addr/file/download/1"
            2 -> url = "$addr/file/export/1"
        }
        val encode = URLEncoder.encode(url, "utf-8")
        result["returnCode"] = 0
        result["addr"] = encode
        return result
    }

3.6 解决请求token限制
在InterceptorConfig中使用excludePathPatterns

override fun addInterceptors(registry: InterceptorRegistry?) {
       registry?.addInterceptor(csrfInterceptor)
                ?.excludePathPatterns("/test/**", "/file/download/**", "/file/export/**")
                ?.addPathPatterns("/**")
    }

或者在拦截器中解决

if (request?.getHeader("token").equals(encryptBkToken)) {
	//token校验
} else if (request?.requestURI.equals("****")){
	//允许下载
} else {}

3.7 关于下载的另一种方法:使用tomcat虚拟目录
从上文可以发现,模板文件是放在项目里面的,如果文件很多那么项目就会很大;并且下载时调用了downLoadExcel方法,多了读取文件输出文件流的操作。使用tomcat虚拟目录可以解决以上问题。
3.7.1 在服务器上创建资源文件夹
在这里插入图片描述
3.7.2 在tomcat下的/conf/Catalina/localhost中增加xml
在这里插入图片描述
如图,docBase为资源路径,path和文件名保持一致,这里注意path随便写也没关系,因为用不到
3.7.3 不需要重启服务器就可以访问到文件,在浏览器输入:http://ip:端口/download/sms_link_template.xls
就可以下载到sms_link_template.xls文件,注意这里的download指的是download.xml的名称,如果xml名称变更,这边路径也要变,和xml中的path无关
3.7.4根据3.7.3的原理改变代码

@Value("\${download.template.xls.sms_link}")
    private var smsLinkTemplate: String = ""
    
@GetMapping("address/{id}")
    fun address(@PathVariable("id") id: Int, req: HttpServletRequest): Map<String, Any> {
        val result = HashMap<String, Any>()
        var url = ""
        val addr = "${req.scheme}://${req.serverName}:${req.serverPort}"
        when (id) {
            1 -> url = "$addr/download/smsLinkTemplate"//注意这个就是3.7.3的访问路径
        }
        val encode = URLEncoder.encode(url, "utf-8")
        result["returnCode"] = 0
        result["addr"] = encode
        return result
    }

然后前台直接调用这个接口返回组合好的路径,直接超链接就能下载了,3.6的token限制也不用管了。
但是我并没有把我代码改了,因为项目简单而且我懒啊

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值