Java下载文件excel问题

时间:2015-09-28 09:37:18

标签: java servlets

我开发了一个从服务器上下载excel文件的代码。

下载a.xlsx文件会显示"我们发现“FileName.xlsx”中的某些内容存在问题。您是否希望我们尝试尽可能多地恢复?如果您信任此工作簿的来源,请单击是"。点击"是"按钮,它显示内容。我可以在修复后打开文件,数据似乎没问题。打开和保存选项均显示错误。但修复后的数据仍然存在。 在服务器中打开文件时没有错误。

我需要做什么吗?

public void downloadFile(String fileName, String filePath) {
    try {
        fileName = URLEncoder.encode(fileName,"UTF-8");
    } catch (UnsupportedEncodingException e1) {
        logger.info("Can not encode file name");
    } 
    response.setContentType("application/octet-stream; charset=UTF-8");
    response.setHeader("Content-Disposition", "attachment;filename="
        + fileName);
        response.setCharacterEncoding("UTF-8");
    try {
        ServletOutputStream out = response.getOutputStream();
        FileInputStream in = new FileInputStream(new File(filePath));
        byte[] outputByte = new byte[4096];
        while (in.read(outputByte, 0, 4096) != -1) {
            out.write(outputByte, 0, 4096);
        }
        in.close();
        out.flush();
        out.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

3 个答案:

答案 0 :(得分:3)

问题出在这里

 while (in.read(outputByte, 0, 4096) != -1) {
     out.write(outputByte, 0, 4096);
 }

当你到达文件的末尾时,你不是在贬低4096而是更少。 您必须保存读取和写入输出的数据量:类似

 int bytesRead=0;
 while ((bytesRead=in.read(outputByte, 0, 4096)) != -1) {
     out.write(outputByte, 0, bytesRead);
 }

答案 1 :(得分:0)

byte[] outputByte = new byte[4096];
while (in.read(outputByte, 0, 4096) != -1) {
      out.write(outputByte, 0, 4096);
}

在此代码中,您总是写入4096个字节。对于您的最后一块数据,您写的数据比读取的数据多(4096次中至少有4095次)。

您必须检查读取的金额并准确写入输出流的读取金额。

int readAmount= 0;
int arrLen = 4096;
byte[] outputByte = new byte[arrLen];
while ((readAmount = in.read(outputByte, 0, arrLen)) != -1) {
      out.write(outputByte, 0, readAmount);
}

答案 2 :(得分:0)

即使我被困在这个问题上大约一个星期。最后,我通过使用下面的代码解决了这个问题并获得了excel输出而没有被破坏。

我是作为一个maven项目做的。

在pom.xml文件

中为Super CSV Core»2.4.0添加以下依赖项
 <!-- https://mvnrepository.com/artifact/net.sf.supercsv/super-csv -->
<dependency>
    <groupId>net.sf.supercsv</groupId>
    <artifactId>super-csv</artifactId>
    <version>2.4.0</version>
</dependency>

现在使用以下代码作为控制器类

CSVFileDownloadController.java

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.supercsv.io.CsvBeanWriter;
import org.supercsv.io.ICsvBeanWriter;
import org.supercsv.prefs.CsvPreference;

import com.rapidvalue.master.employee.vo.Book;

@Controller
public class CSVFileDownloadController {
      @RequestMapping(value = "/downloadCSV")
        public void downloadCSV(HttpServletResponse response) throws IOException {

            String csvFileName = "books.csv";

            response.setContentType("text/csv");

            // creates mock data
            String headerKey = "Content-Disposition";
            String headerValue = String.format("attachment; filename=\"%s\"",
                    csvFileName);
            response.setHeader(headerKey, headerValue);

            Book book1 = new Book("Effective Java", "Java Best Practices",
                    "Joshua Bloch", "Addision-Wesley", "0321356683", "05/08/2008",
                    38);

            Book book2 = new Book("Head First Java", "Java for Beginners",
                    "Kathy Sierra & Bert Bates", "O'Reilly Media", "0321356683",
                    "02/09/2005", 30);

            Book book3 = new Book("Thinking in Java", "Java Core In-depth",
                    "Bruce Eckel", "Prentice Hall", "0131872486", "02/26/2006", 45);

            Book book4 = new Book("Java Generics and Collections",
                    "Comprehensive guide to generics and collections",
                    "Naftalin & Philip Wadler", "O'Reilly Media", "0596527756",
                    "10/24/2006", 27);

            List<Book> listBooks = Arrays.asList(book1, book2, book3, book4);

            // uses the Super CSV API to generate CSV data from the model data
            ICsvBeanWriter csvWriter = new CsvBeanWriter(response.getWriter(),
                    CsvPreference.STANDARD_PREFERENCE);

            String[] header = { "Title", "Description", "Author", "Publisher",
                    "isbn", "PublishedDate", "Price" };

            csvWriter.writeHeader(header);

            for (Book aBook : listBooks) {
                csvWriter.write(aBook, header);
            }

            csvWriter.close();
        }
    }

将此用作模型数据类

Book.java

public class Book {
    private String title;
    private String description;
    private String author;
    private String publisher;
    private String isbn;
    private String publishedDate;
    private float price;

    public Book() {
    }

    public Book(String title, String description, String author, String publisher,
            String isbn, String publishedDate, float price) {
        this.title = title;
        this.description = description;
        this.author = author;
        this.publisher = publisher;
        this.isbn = isbn;
        this.publishedDate = publishedDate;
        this.price = price;
    }

    // getters and setters...
}

现在在服务器上运行此代码。点击浏览器中的URL。您的文件将毫无问题地下载。希望这会有所帮助! :)