(手擼)SringBoot統一返回格式的接口數據封裝成excel表格並且輸出流下載

package com.lalala.ami.common;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.doreen.core.annotation.Api;
import com.doreen.core.annotation.Item;
import com.doreen.core.annotation.JSON;
import com.doreen.core.aop.bean.Result;
import com.doreen.core.exception.ErrorEnum;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * @author 
 * @version 1.0
 * @date 2020/6/19 0019 17:09
 * @description
 */
@RestController
public class ExportExcelController {
    @Value("${server.port}")
    private String port;

    private Log log = LogFactory.getLog(ExportExcelController.class);

    @Api("導出Excel")
    @RequestMapping("/excel")
    @JSON({@Item(name = "url", desc = "請求路徑", must = true),
            @Item(name = "param", desc = "請求參數", must = true),
            @Item(name = "head", desc = "要生成的表頭", must = true)})
    public void excel(@RequestHeader Map<String, String> header, @RequestBody JSONObject jsonObject, HttpServletResponse httpResponse) throws URISyntaxException, IOException {
        String url = "http://127.0.0.1:" + port + "/" + jsonObject.getString("url");
        HttpClient httpClient = HttpClients.createDefault();
        URIBuilder uriBuilder = new URIBuilder(url);
        HttpPost postParam = new HttpPost(uriBuilder.build());
        header.keySet().forEach(key -> {
            //首字母和橫槓後面的字母轉換成大寫
            key = this.convertToUpcase(key);
            if (!("Content-Length".equals(key) || "content-length".equals(key))) {
                postParam.setHeader(key, header.get(key));
            }
        });
        JSONObject param = jsonObject.getJSONObject("param");
        StringEntity entity = new StringEntity(param.toString(), Charset.defaultCharset());
        entity.setContentType("application/json");
        postParam.setEntity(entity);
        HttpResponse response = httpClient.execute(postParam);
        int code = response.getStatusLine().getStatusCode();
        if (code != 200){
            return;
        }
        exportExcel(response, jsonObject, httpResponse);
    }
//不知爲何後端接受到的請求頭是小寫的,爲了模擬真實請求只能再轉換爲大寫
    private String convertToUpcase(String key) {
        char[] chars = key.toCharArray();
        StringBuilder res = new StringBuilder();
        for (int i = 0; i <chars.length ; i++) {
            if(i==0){
                res.append(Character.toUpperCase(chars[i]));
                continue;
            }
            if('-'==chars[i]){
                i++;
                res.append("-").append(Character.toUpperCase(chars[i]));
                continue;
            }
            res.append(chars[i]);
        }
        return res.toString();
    }

    private void exportExcel(HttpResponse response, JSONObject
            jsonObject, HttpServletResponse httpResponse) throws IOException {
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet();
        sheet.setDefaultColumnWidth((short) 18);
        //獲取表頭
        JSONObject head = jsonObject.getJSONObject("head");
        String[] heads = head.keySet().toArray(new String[]{});
        //獲取數據
        HttpEntity entity = response.getEntity();
        BufferedReader bufferedReader = null;
        try {
            bufferedReader = new BufferedReader(
                    new InputStreamReader(entity.getContent(), StandardCharsets.UTF_8), 8 * 1024);
            StringBuilder entityStringBuilder = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                entityStringBuilder.append(line);
            }
            //生成JsonObject
            JSONObject resJsonObj = JSONObject.parseObject(entityStringBuilder.toString());
            JSONObject data = resJsonObj.getJSONObject("data");
            if(data == null){
                return;
            }
            JSONArray list = data.getJSONArray("list");
            //創建標題行
            Row row = sheet.createRow(0);
            for (int i = 0; i < heads.length; i++) {
                Cell cell = row.createCell(i);
                cell.setCellType(CellType.STRING);
                cell.setCellValue(head.getString(heads[i]));
            }
            //創建數據行
            for (int i = 0; i < list.size(); i++) {
                Row dataRow = sheet.createRow(i + 1);
                JSONObject vals = (JSONObject) list.get(i);
                for (int j = 0; j < heads.length; j++) {
                    Cell cell = dataRow.createCell(j);
                    cell.setCellType(CellType.STRING);
                    cell.setCellValue(vals.getString(heads[j]));
                }
            }
            httpResponse.setContentType("application/octet-stream");
            httpResponse.setHeader("Content-Disposition", "attachment;fileName=" + "export.xls");
            ServletOutputStream outputStream = httpResponse.getOutputStream();
            workbook.write(outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(bufferedReader!=null){
                bufferedReader.close();
            }
        }
    }

}



貼一下前端代碼:
$(document).ready(function(){
$("button").click(function(){

request();


});
function request () {
const req = new XMLHttpRequest();
req.open('POST', 'http://127.0.0.1:8080/excel', true);
req.responseType = 'blob';
req.setRequestHeader('Content-Type', 'application/json');
req.onload = function() {
const data = req.response;
const a = document.createElement('a');
const blob = new Blob([data]);
const blobUrl = window.URL.createObjectURL(blob);
download(blobUrl) ;
};
req.send(JSON.stringify({

"url": "lvdn/query/freezeData/getGridMeterFreezeData",

"param": {
"Id": "4fbs3a547092",
"mepe":"sub",
"dataType":"day",
"startTime":"2020-05-01 00:00:00",
"endTime":"2020-07-01 00:00:00"
},
"head":{
"meterName":"電錶名稱",
"meterNo":"電錶序號",
"kat":"電能示值"
}
}));
};
function download(blobUrl) {
const a = document.createElement('a');
a.style.display = 'none';
a.download = '11111.xls';
a.href = blobUrl;
a.click();
document.body.removeChild(a);
}
});

說幾個坑:1.這種方式前端需要特殊處理,XMLHttpRequest用這個東西,具體怎麼樣我不會,百度就好。

                   2.後端接收到requestHeader之後無怨無gu的轉換成了小寫,爲了模擬真實請求我們要再改回大寫。

                   3.        httpResponse.setContentType("application/octet-stream"); httpResponse.setHeader("Content-Disposition",                                    "attachment;fileName=" + "export.xls");這個響應頭不加的話據說下載的文件打不開。

                  4.適用場景:爲統一的返回接口做xls包裝,相當於我們後端去調用原來接口,把數據拿到再包裝。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章