2015-09-28 78 views
1

我开发了一个用于从服务器上下载excel文件的代码。Java下载文件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(); 
    } 
} 

回答

2

问题就出在这里

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

当你到达你是不是rading 4096文件,但东西少的结束。 你必须为你节省了多少数据读取和写入到输出:像

int bytesRead=0; 
while ((bytesRead=in.read(outputByte, 0, 4096)) != -1) { 
    out.write(outputByte, 0, bytesRead); 
} 
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); 
} 
0

即使我被这个问题困住了大约1周。最后,我解决了这个问题,并得到了一个excel输出,而不会被使用下面的代码损坏。

我做了一个maven项目。

添加超级CSV睿以下依赖»2.4.0在你的pom.xml文件

<!-- 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... 
} 

现在在服务器上运行此代码。在浏览器中点击网址。您的文件将被下载没有任何问题。希望这会有所帮助! :)