在内存中上传,修改和下载相同的文件

时间:2017-12-10 23:32:32

标签: spring spring-mvc spring-boot apache-poi

我必须创建一个允许用户上传特定Excel文件的应用程序。 Sumarizing,系统需要接收文件,在特定单元格中写入内容并返回修改为视图的相同文件,然后,用户可以下载此新文件。

我使用Apache POI修改excel文件,但我不知道如何将此文件返回到视图。

上传视图:

<form method="POST" enctype="multipart/form-data" th:action="@{/pessoa/lote}">
            <table>
                <tr><td>File to upload:</td><td><input type="file" name="file" /></td></tr>
                <tr><td></td><td><input type="submit" value="Upload" /></td></tr>
            </table>
</form>

控制器:我不知道自己需要做什么,我称之为#34; consultaLote&#34;来自名为&#34; ConsultaPessoaService&#34;的服务。

@RequestMapping(value = "/lote", method = RequestMethod.POST)
public String handleFileUpload(@RequestParam("file") MultipartFile file,
        RedirectAttributes redirectAttributes) {
    try {
        cpService.consultaLote(file);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    redirectAttributes.addFlashAttribute("message",
            "You successfully uploaded " + file.getOriginalFilename() + "!");

    return "redirect:/";
}

在服务中,我可以读取和编辑文件,然后生成一个FileOutputStream。这时我不知道如何继续,我需要使用控制器将文件返回到视图,但我不知道如何:

@Service
public class ConsultaPessoaService {

    public FileOutputStream consultaLote(MultipartFile file) throws IOException {
        DataFormatter formatter = new DataFormatter();

        File convFile = new File(file.getOriginalFilename());
        convFile.createNewFile(); 
        FileOutputStream fos = new FileOutputStream(convFile); 
        fos.write(file.getBytes());
        fos.close(); 

        FileInputStream inputStream = new FileInputStream(convFile);

        Workbook workbook = new XSSFWorkbook(inputStream);
        Sheet firstSheet = workbook.getSheetAt(0);

        Iterator<Row> iterator = firstSheet.iterator();
        while (iterator.hasNext()) {

            Row nextRow = iterator.next();
            System.out.println(formatter.formatCellValue(nextRow.getCell(3)));

            nextRow.getCell(3).setCellValue("test");
        }

            FileOutputStream outputStream = new FileOutputStream("arquivot.xlsx");
            workbook.write(outputStream);
            workbook.close();

            outputStream.flush();
            outputStream.close();
            return outputStream;
    }
}

1 个答案:

答案 0 :(得分:1)

您应该从consultaLote方法返回一个字节数组。方法返回类型将为byte[],因为您需要此字节数组来编写 httpservlet输出流

public byte[] consultaLote(MultipartFile file) throws IOException {
    //whatever changes you want, do it here. I am going to converting part
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    workbook.write(baos);
    // before returning you can close your your ByteArrayOutputStream
    //baos.close();
    return baos.toByteArray();
}

现在来到你的控制器。我们将字节数组从OutputStream写入HttpservletResponse

@RequestMapping(value = "/lote", method = RequestMethod.POST)
public String handleFileUpload(@RequestParam("file") MultipartFile file,
        RedirectAttributes redirectAttributes,HttpServletResponse response) {
    byte[] fileBytes = null;
    String reportName="yourReportName";
    try {
        fileBytes = cpService.consultaLote(file);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    if(fileBytes !=null){
        response.setHeader("Content-Disposition", "attachment; filename=" + reportName + ".xls");
        response.setContentType("application/xls");
        response.getOutputStream().write(fileBytes);
        response.getOutputStream().flush();
    }
    redirectAttributes.addFlashAttribute("message",
            "You successfully uploaded " + file.getOriginalFilename() + "!");

    return "redirect:/";
}

希望这会有所帮助。