我开发了一个从服务器上下载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();
}
}
答案 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。您的文件将毫无问题地下载。希望这会有所帮助! :)