首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Spring + Nextjs中以Excel的形式下载列表

在Spring + Nextjs中以Excel的形式下载列表
EN

Stack Overflow用户
提问于 2022-09-06 16:03:21
回答 1查看 69关注 0票数 0

我正在尝试从我的Nextjs前端点击一个按钮,下载一个excel列表。我的后端是用Spring编写的,我需要从这里发送文件,这样用户就可以在点击链接时下载它。

我的问题是:

如果在本例中,如果我想按一下按钮下载文件,那么

  1. 最佳实践是什么?
  2. ,返回类型和内容类型应该是什么?

我已经尝试过的东西,:通过改变内容类型和媒体类型。我想不知何故,我弄乱了触发API的内容类型和返回类型。

我的后端代码文件:

ExcelExporter.java

代码语言:javascript
运行
复制
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;

public class ExcelExporter {
    private final XSSFWorkbook workbook;
    private XSSFSheet sheet;
    private final List<Debt> debts;

    String[] columns = {"Reference", "Title", "Descrip", "Gateway", "Status", "Amount (USD)", "Paid", "Name"};

    public ExcelExporter(List<Debt> debts) {
        this.debts = debts;
        workbook = new XSSFWorkbook();
    }


    private void writeHeaderLine() {
        sheet = workbook.createSheet("Payment Report");

        CellStyle headerCellStyle = workbook.createCellStyle();

        // setting up header fonts
        XSSFFont headerFont = workbook.createFont();
        headerFont.setBold(true);
        headerFont.setFontHeight(16);

        // setting up header cell style
        headerCellStyle.setFont(headerFont);

        // header row creation
        Row headerRow = sheet.createRow(0);

        for(int col=0; col <columns.length; col++){
            createCell(headerRow, col, columns[col], headerCellStyle);
        }

    }

    private void createCell(Row row, int columnCount, String value, CellStyle style) {
        sheet.autoSizeColumn(columnCount);
        Cell cell = row.createCell(columnCount);
        cell.setCellValue(value);
        cell.setCellStyle(style);
    }

    private void writeDataLines() {
        int rowIdx = 1;

        CellStyle style = workbook.createCellStyle();
        XSSFFont font = workbook.createFont();
        font.setFontHeight(14);
        style.setFont(font);

        for (Debt debt : debts) {
            Row dataRow = sheet.createRow(rowIdx++);
            int columnCount = 0;

            createCell(dataRow, columnCount++, debt.getRef(), style);
            createCell(dataRow, columnCount++, debt.getTitle(), style);
            createCell(dataRow, columnCount++, debt.getDescrip(), style);
            createCell(dataRow, columnCount++, debt.getGateway(), style);
            createCell(dataRow, columnCount++, debt.getStat(), style);
            createCell(dataRow, columnCount++, debt.getAmount(), style);
            createCell(dataRow, columnCount++, debt.getPaid(), style);
            createCell(dataRow, columnCount++, debt.getName(), style);

        }
    }

    public ByteArrayInputStream export() throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        try {
            writeHeaderLine();
            writeDataLines();
            workbook.write(outputStream);
            return new ByteArrayInputStream(outputStream.toByteArray());
        }catch (IOException e){
            throw new RuntimeException("fail To Import Data To Excel File: " + e.getMessage());
        }

    }
}

主计长:

代码语言:javascript
运行
复制
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("report")
public class ReportController {

    @GetMapping(value = "export-to-excel", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public byte[] exportReport() throws IOException {

        List<Debt> debtSummaries = new ArrayList<Debt>();
        debt.add(new Debt("AA", "BB", "CC", "DD", "EE", "FF", "GG", "HH"));
        debt.add(new Debt("AA", "BB", "CC", "DD", "EE", "FF", "GG", "HH"));
        debt.add(new Debt("AA", "BB", "CC", "DD", "EE", "FF", "GG", "HH"));
        debt.add(new Debt("AA", "BB", "CC", "DD", "EE", "FF", "GG", "HH"));
        
        DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss");
        String currentDateTime = dateFormatter.format(new Date());

        String headerKey = HttpHeaders.CONTENT_DISPOSITION;
        String headerValue = "attachment; filename=PaymentReport_" + currentDateTime + ".xlsx";
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add(headerKey, headerValue);

        ExcelExporter excelExporter = new ExcelExporter(debtSummaries);
        ByteArrayInputStream in = excelExporter.export();


        return IOUtils.toByteArray(in);
}

Debt.java

代码语言:javascript
运行
复制
@Getter
@Setter
@AllArgsConstructor
public class Debt {

    String ref;

    String title;

    String descrip;

    String gateway;

    String stat;

    String amount;

    String paid;

    String name;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-06 18:15:06

直接返回字节数组并不是正确的方法。我不能保证这是最好的方法。但你可以这样做。

代码语言:javascript
运行
复制
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;


@RestController
@RequiredArgsConstructor
@RequestMapping("report")
public class ReportController {

    @GetMapping(value = "export-to-excel", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public ResponseEntity<Resource> exportReport() throws IOException {

        //Other actions you want to do... 

        ExcelExporter excelExporter = new ExcelExporter(debtSummaries);
        ByteArrayInputStream in = excelExporter.export();

        ByteArrayResource resource = new ByteArrayResource(in.readAllBytes());

        return ResponseEntity.ok()
                .headers(headers)
                .contentLength(resource.contentLength())
                .contentType(MediaType.parseMediaType("application/vnd.ms-excel"))
                .body(resource);
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73624888

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档