SpringBoot 下的Excel文件损坏与内容乱码问题
序言
随着打包部署的方式的改变,原本正常运行的代码可能带来一些新的问题,比如我们现在使用SpringBoot 的方式生成Jar包直接运行,就会对我们再在Resource下的Excel文件产生影响,导入与预期不符的情况发生cuiyaonan2000@163.com
比如:我们会在工程中提供一些模板(Excel文件),然后供前端调用下载,但是下载后内容时乱码,或者不能正常的打开该文件
打包问题
我们在通过编译后发现 放置在target目录下的excel文件打不开了。因为原本文件就打不开了,所以你在后期下载的时候肯定就有问题。
原因:SpringBoot会对resources下文件进行压缩,导致word,excel格式异常cuiyaonan2000@163.com
增加如下的配置,告诉Springboot 相关的文件不要压缩
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
<nonFilteredFileExtension>docx</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
关于Excel等特殊文件的以流的方式下载的问题
看如下我们经常使用的文件下载或者复制的代码
public static void main(String[] args) {
String inputFileName = "C:\\cuiyaonan2000@163.com\\123.xlsx"; // 输入文件名
String outputFileName = "C:\\cuiyaonan2000@163.com\\copy-123.xlsx"; // 输出文件名
try (FileReader fr = new FileReader(inputFileName);
FileWriter fw = new FileWriter(outputFileName)) {
char[] buffer = new char[1024]; // 缓冲数组
int length;
while ((length = fr.read(buffer)) != -1) {
fw.write(buffer, 0, length); // 将读取的内容写入输出文件
}
} catch (IOException e) {
e.printStackTrace();
}
}
如果是文本文件txt,csv.什么的完全没问题,但是如果是Excel这种文件,内容就会是乱码或者显示文件已经损坏
那我们再换一种方式来考本文件
public static void main(String[] args) throws IOException {
try {
FileOutputStream os = new FileOutputStream(new File("C:\\\\cuiyaonan2000@163.com\\\\123.xlsx"));
FileInputStream resource = new FileInputStream("C:\\\\cuiyaonan2000@163.com\\\\copy-123.xlsx");
FileCopyUtils.copy(resource, os);
System.out.print("SUCEESS");
} catch (Exception e) {
e.printStackTrace();
}
}
如上的拷贝就没有任何问题,那我们看看FileCopyUtils.copy(resource.getInputStream(), os);的源码给你我们的byte[] 字节数组拷贝的区别是什么.
因为InputStream 或者OutputStream 本身就是字节流不涉及什么编码格式.,像FileInput ,FileOut就会设计编码格式,但是我们在创建他们的时候还不能直接设置编码格式,需要经过一圈的包装转换才能设置
BufferedWriter writer = new BufferedWriter (new OutputStreamWriter (new FileOutputStream (filePath,true),"UTF-8"));
FileWriter writer = new FileWriter(filePath,true);