2015-09-28 53 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... 
} 

現在在服務器上運行此代碼。在瀏覽器中點擊網址。您的文件將被下載沒有任何問題。希望這會有所幫助! :)