项目实训5——实现根据用户编写的JSON 从数据库中查找数据的功能

1.最终确定要求用户上传的json格式

首先我们进一步规范了json的格式,增加了type字段,代表用户想要上传数据(insert)还是查找数据(select);增加了key字段,用来存储密钥。示例如下:

{"dbname":"student","chartsname":["jibenxinxi"],"metas":{"jibenxinxi":{"id":"7","tid":"2","wage":"10.9","des":"jdbctest"}},"type":"insert","key":"1"}

2.前后端通过文件流来传输查询结果

因为用户需求不同,从查询到的字段也不同,且有可能用户需要查找大量的数据,综上查询结果直接用表格渲染到前端是不现实的。所以我决定通过exel文件流将后端查询到的数据返回给前端。

前端通过ajaxshix,代码如下:

downloadExel(){
      // 构造XMLHttpRequest对象
      let xmlRequest = new XMLHttpRequest();
      // 发送get请求
      xmlRequest.open("GET", "api/fileDownLoad?aid="+this.application_id, true);
      // 设置响应类型
      xmlRequest.responseType = "blob";
      // 发送请求
      xmlRequest.send([]);

      // 请求获得响应之后,触发下面的回调函数
      xmlRequest.onload = function(oEvent) {
        // 当时满足下面的状态码的时候,视为下载成功
        if ((xmlRequest.status >= 200 && xmlRequest.status < 300) || xmlRequest.status === 304) {

          // 从xmlRequest对象中获取响应的内容
          let content = xmlRequest.response;

          /*
            从xmlRequest的响应头中获取文件名字符串
            因为我们将文件以流的形式返回前端,返回的文件没有文件名
            因此在后端处理的时候,我们将文件名放到响应头中
            然后在前端从响应头中获取文件名
  */
          let dispositionStr = xmlRequest.getResponseHeader('content-disposition');
          if (dispositionStr == null || dispositionStr === "") {
            alert("下载失败!");
            return;
          }

          // 获取文件名
          let dispositionArr = dispositionStr.split(";");
          // 我们的文件名可能含有汉字,因此在后端进行了UTF-8编码处理,此处进行解码
          let fileName = decodeURIComponent(dispositionArr[1]);

          // 利用response的响应内容构造一个Blob对象(通过Blob对象进行下载)
          let blob = new Blob([content]);

          // 创建一个隐藏的用来下载文件的a标签
          let elink = document.createElement('a');
          elink.download = fileName;
          elink.style.display = 'none';

          /*
            将blob文件对象转换为内存中对象,并将生成的对象赋给隐藏的a标签
            bolb对象会暂时存储在客户端的内存中,
            使用URL.createObjectURL()方法可以创建指向内存文件对象的临时url
            使用createObjectURL可以节省性能并更快速,只不过需要在不使用的情况下手动释放内存
            FileReader.readAsDataURL返回文件的base64字符串,比blob url消耗更多内存,但是在不用的时候会自动从内存中清除(通过垃圾回收机制)
  */
          const src = URL.createObjectURL(blob);
          elink.href = src;
          document.body.appendChild(elink);

          // 模拟点击下载事件,进行下载
          elink.click();

          // 点击之后,移除我们定义的隐藏a标签
          document.body.removeChild(elink);

          // 移除文件对象
          URL.revokeObjectURL(src)
        }
      }
    }

后端利用了阿里提供的easyExcel包
2.1导入:


```javascript

```xml
<!--导入EasyExcel的Jar包-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.2.4</version>
        </dependency>
        <!--xls-->

2.2只需要一句话,传入要求的参数既可以了。

String fileName = "C:\\Users\\86187\\Desktop\\study\\"+"申请"+this.application_id+"查询结果"+".xlsx";

List<List<String>> list = new ArrayList<>();
EasyExcel.write(fileName).head(list).sheet("模板").doWrite(fun(text));

3.使用JDBC从数据库中查询数据

因为这是一个可以适用于用户传入的不同的JSON的通用方法,所以现有框架都很难套用,所以我选择了直接使用JDBC编写。

  public List<List<Object>> fun(String text) {
        List<List<Object>> result = new ArrayList<>();
        for (String s : this.chartnames1) {
            String metas = "";
            List<String> metas0 = new ArrayList<>();
            for (List<PDetail> pDetails : this.chartnames2) {
                for (PDetail pDetail : pDetails) {
                    System.out.println(pDetail);
                    if(pDetail.getChartname().equals(s)){
                        metas += pDetail.getMeta() + ",";
                        metas0.add(pDetail.getMeta());
                    }else {
                        if(!metas.equals(""))
                            break;
                    }
                }
            }
            metas = metas.substring(0,metas.length()-1);
            result.addAll(selectData(s,metas,metas0));
        }
        return result;
    }

4.效果展示
点击提交后,弹出下载页面:
在这里插入图片描述
点击按钮后,可以下载得到查询结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值