【问题标题】:Convert JSON Data into Excel File Download in Javascript将 JSON 数据转换为 Excel 文件 在 Javascript 中下载
【发布时间】:2018-07-05 05:37:37
【问题描述】:

我有一个 AJAX POST 请求以 JSON 数组的形式取回数据。 我想将此收到的 JSON 数据转换为 Excel 文件(不是 CSV)以供下载(单击按钮),请帮助。 JSON 数据的每个 JSON 行可能包含空白值和缺失字段。

我在客户端使用 Javascript 进行了尝试,但没有在 Java 服务器端尝试,在这种情况下,我将不得不在 AJAX 端点方法中使用 @Produces(MediaType.MULTIPART_FORM_DATA),这是我可以尝试的,但认为它很复杂.

a) AJAX 请求代码:

function fileUploadFunction() {

    var file = $('input[name="file"').get(0).files[0];
    var formData = new FormData();

    if(file.name != null) {
        document.getElementById("btnUpload").disabled = false;

        formData.append('file', file);
        $.ajax({
            url : "<%=request.getContextPath()%>/rest/upload/upload",
            type : "POST",
            data : formData,
            cache : false,
            contentType : false,
            processData : false,
            success : function(response) {
                //Store result in Session and Enable Download button
                var cacheString = JSON.stringify(response, null, 2);
                console.log("-----------------> cacheString is: " + cacheString);
                if(cacheString != null && cacheString != "[]") {
                    document.getElementById("download").disabled = false;
                }
                var sessionresponse = sessionStorage.setItem("i98779", cacheString); 

                console.log("response is: " + response);
                console.log("cacheString is: " + cacheString);
                excelDownload(cacheString);
                //createTable(response);
                //https://stackoverflow.com/questions/47330520/how-to-export-json-object-into-excel-using-javascript-or-jquery

            },

            error : function(jqXHR, textStatus, errorThrown) {
                console.log(errorThrown);
                alert("Error: " + errorThrown);
            }

        });//ajax ends

    }//if ends

}//Function ends

b) 从 AJAX POST 请求接收的 JSON 示例数据:

[
    {
    "entityid":2,
    "firstname":"George",
    "lastname":"Bush",
    "ssn":"",
    "city":"Houston",
    "state":"TX",
    "country":"USA",
    "zipcode":""
    },
    {
    "entityid": 8,
    "firstname": "Jim",
    "lastname": "Macron",
    "ssn": "888-88-8888",
    "city": "Paris",
    "state": "NY",
    "country": "France",
    "zipcode": "T789J"
    },
    {
    "entityid": 11,
    "firstname": "Angela",
    "lastname": "Merkel",
    "city": "Saxony",
    "zipcode": ""
    },
    {
    "entityid": 7,
    "firstname": "Donald",
    "lastname": "Trump",
    "ssn": "777-77-7777",
    "city": "Washington D.C.",
    "state": "DC",
    "country": "USA",
    "zipcode": "70000"
    }

]

【问题讨论】:

  • 你接受从 Java 后端生成 Excel 的答案吗?
  • 当然,那也应该没问题。非常感谢。

标签: javascript json ajax excel type-conversion


【解决方案1】:

这是一种从 WebService(Resteasy 实现)生成 excel 的方法,经过测试并且可以正常工作:

@POST
    @Path("/excelpost")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response downloadFilePost( ) throws IOException {

         XSSFWorkbook workbook = new XSSFWorkbook();
            XSSFSheet sheet = workbook.createSheet("Datatypes in Java");
            Object[][] datatypes = {
                    {"Datatype", "Type", "Size(in bytes)"},
                    {"int", "Primitive", 2},
                    {"float", "Primitive", 4},
                    {"double", "Primitive", 8},
                    {"char", "Primitive", 1},
                    {"String", "Non-Primitive", "No fixed size"}
            };

            int rowNum = 0;
            System.out.println("Creating excel");

            for (Object[] datatype : datatypes) {
                Row row = sheet.createRow(rowNum++);
                int colNum = 0;
                for (Object field : datatype) {
                    Cell cell = row.createCell(colNum++);
                    if (field instanceof String) {
                        cell.setCellValue((String) field);
                    } else if (field instanceof Integer) {
                        cell.setCellValue((Integer) field);
                    }
                }
            }

                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                workbook.write(outputStream);
                workbook.close();


            return Response.status(200).header("Access-Control-Allow-Origin", "*")
                    .header("Content-Disposition", "attachment;filename='fileName.xlsx'")
                    .header("Access-Control-Allow-Headers", "origin, content-type, accept, authorization")
                    .header("Access-Control-Allow-Credentials", "true")
                    .header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD")
                    .header("Access-Control-Max-Age", "1209600").entity( new ByteArrayInputStream(outputStream.toByteArray() )).build();


    }

这是管理 Excel 文件的 maven 依赖项:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.17</version>
</dependency>

您可以轻松地添加适当的注释和 web 参数来管理从您的服务启动后的文件输入:

@POST
@Path("/excelpost")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response downloadFilePost(MultipartFormDataInput input)
   .......

如果有帮助请告诉我...

【讨论】:

  • @Blackjack,感谢您的帮助,感谢您,但出现以下错误:org.apache.catalina.core.StandardWrapperValve 调用严重:Servlet.service() for servlet [restserver] in context with path [/restserver] 引发异常 [java.lang.ClassCastException: org.apache.poi.xssf.usermodel.XSSFCell 无法转换为 com.google.common.collect.Table$Cell] 根本原因 java.lang.ClassCastException: org .apache.poi.xssf.usermodel.XSSFCell 无法转换为 com.google.common.collect.Table$Cell
  • 被要求 CAST 如下: for (Object[] datatype : datatypes) { Row row = sheet.createRow(rowNum++); int colNum = 0; for (Object field : datatype) { Cell cell = (Cell) row.createCell(colNum++); if (field instanceof String) { ((org.apache.poi.ss.usermodel.Cell) cell).setCellValue((String) field); } else if (field instanceof Integer) { ((org.apache.poi.ss.usermodel.Cell) cell).setCellValue((Integer) field); } } }
  • 这是因为您试图将 com.google.common.collect.Table$Cell 放入无法接受该值的 Excel 单元格中。您需要取出该值并将该值放入 excel 单元格对象。
  • 好的,更改为下面并获取文件下载但带有垃圾字符: for (Object[] datatype : datatypes) { Row row = sheet.createRow(rowNum++); int colNum = 0; for(对象字段:数据类型){ org.apache.poi.ss.usermodel.Cell cell = row.createCell(colNum++); if (field instanceof String) { cell.setCellValue((String) field); } else if (field instanceof Integer) { cell.setCellValue((Integer) field); } } }
  • 请发布你的实现我不明白你在做什么。基本上它是你将值传递给 excel 单元格的方式。
【解决方案2】:

@Blackjack,下面是代码...

1) 点击按钮调用函数。这具有将 Excel 文件传递​​给 REST Endpoint 函数的 AJAX 调用:

function fileUploadFunction() {

    var file = $('input[name="file"').get(0).files[0];
    var formData = new FormData();

    if(file.name != null) {
        document.getElementById("btnUpload").disabled = false;

        formData.append('file', file);
        $.ajax({
            url : "<%=request.getContextPath()%>/rest/upload/bulkSearch",
            type : "POST",
            data : formData,
            cache : false,
            contentType : false,
            processData : false,
            success : function(response) {
                //Store result in Session and Enable Download button
                var cacheString = JSON.stringify(response, null, 2);
                console.log("-----------------> cacheString is: " + cacheString);
                if(cacheString != null && cacheString != "[]") {
                    document.getElementById("download").disabled = false;
                }
                var sessionresponse = sessionStorage.setItem("i98779", cacheString); 

                console.log("response is: " + response);
                console.log("cacheString is: " + cacheString);
                //excelDownload(cacheString);
                //createTable(response);
                //https://stackoverflow.com/questions/47330520/how-to-export-json-object-into-excel-using-javascript-or-jquery

            },

            error : function(jqXHR, textStatus, errorThrown) {
                console.log(errorThrown);
                alert("Error: " + errorThrown);
            }

        });//ajax ends

    }//if ends

}//Function ends

2) REST端点函数:

@POST 
@Consumes(MediaType.MULTIPART_FORM_DATA) 
@Produces(MediaType.APPLICATION_OCTET_STREAM)
@Path("/bulkSearch") 
public Response bulkSearch( 
    @FormDataParam("file") InputStream uploadedInputStream, 
    @FormDataParam("file") FormDataContentDisposition fileDetail) throws IOException { 

    System.out.println("Entered uploadFile method");
    System.out.println("uploadedInputStream is: " + uploadedInputStream);
    System.out.println("fileDetail is: " + fileDetail.toString());

    String returnJSON = null;
    List<User> usersList = null;
    ObjectMapper uploadMapper = new ObjectMapper();

    //System.out.println("File name is: " + fileDetail.getFileName());
    //System.out.println("File size is : " + fileDetail.getSize());
    //System.out.println("File size is : " + fileDetail.getType());

    // check if all form parameters are provided 
    if (uploadedInputStream == null || fileDetail == null) 
        return Response.status(400).entity("Invalid form data").build();

    System.out.println("Checked Input file is ok");

    System.out.println("----------------------------------------------------------------");
    XSSFWorkbook workbook = new XSSFWorkbook();
    XSSFSheet sheet = workbook.createSheet("Datatypes in Java");
    Object[][] datatypes = {
            {"Datatype", "Type", "Size(in bytes)"},
            {"int", "Primitive", 2},
            {"float", "Primitive", 4},
            {"double", "Primitive", 8},
            {"char", "Primitive", 1},
            {"String", "Non-Primitive", "No fixed size"}
    };

    int rowNum = 0;
    System.out.println("Creating excel");

    for (Object[] datatype : datatypes) {
        Row row = sheet.createRow(rowNum++);
        int colNum = 0;
        for (Object field : datatype) {
            org.apache.poi.ss.usermodel.Cell cell = row.createCell(colNum++);
            if (field instanceof String) {
                cell.setCellValue((String) field);
            } else if (field instanceof Integer) {
                cell.setCellValue((Integer) field);
            }
        }
    }

        System.out.println("For loop done");

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); //-----> no reference to excel cells here
        System.out.println("outputstream done");
        workbook.write(outputStream);
        System.out.println("workbook.write done");
        workbook.close();
        System.out.println("workbook closed");


    return Response.status(200).header("Access-Control-Allow-Origin", "*")
            .header("Content-Disposition", "attachment;filename='fileName.xlsx'")
            .header("Access-Control-Allow-Headers", "origin, content-type, accept, authorization")
            .header("Access-Control-Allow-Credentials", "true")
            .header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD")
            .header("Access-Control-Max-Age", "1209600").entity( new ByteArrayInputStream(outputStream.toByteArray() )).build();



} 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-15
    • 2016-12-18
    • 2015-04-01
    • 2023-02-14
    • 2015-05-07
    相关资源
    最近更新 更多