使用資料庫(mysql)欄位儲存檔案
資料庫:mysql + mybatis
檔案:本專案儲存的是excel檔案,其他檔案應該也是適用的
最近由於專案原因,需將檔案儲存到資料庫中,最先開始設計新增一個型別為blob的欄位,結果儲存沒有問題,但下載的時候如果該excel檔案裡包含特殊公式,或者版本不相容時,會丟失樣式和內容,最終解決方式:將bolb型別改為mediumtext(或則text),text最大支援64kb的檔案,mediumtext最大支援16M的檔案,可視情況進行設定
例如:alter table ab_report_history add column fileContent mediumtext COMMENT '檔案內容';
重點:儲存時將檔案轉換為String後,base64編碼,下載時將內容取出來,base64解碼
示例:
java程式碼:
儲存時:
AbReportHistory record = new AbReportHistory();
record.setFileContent(FileUtil.encodeBase64File(myfile)); //注意此方法
下載時:
new BASE64Decoder().decodeBuffer(編碼後的string); //通過此方法解碼
java欄位型別:
private String fileContent;
mybatis
<result column="fileContent" jdbcType="VARCHAR" property="fileContent" />
--------------------------------以上是將檔案儲存到資料庫的關鍵內容--------------------------------------------------------
以下提供相關工具類:
package *.*.*.*; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import org.springframework.web.multipart.MultipartFile; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; /** * 檔案操作工具類 * @author sunddylee * @date 2016年12月20日 * */ public class FileUtil { /** * NIO way * 讀取excel檔案 * @param filePath * @param fileName * @throws Exception */ public static byte[] readExcelFiletoByteArray(String filePath) throws Exception { File f = new File(filePath); if (!f.exists()) { throw new FileNotFoundException(filePath); } FileChannel channel = null; FileInputStream fs = null; try { fs = new FileInputStream(f); channel = fs.getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size()); while ((channel.read(byteBuffer)) > 0) { // do nothing // System.out.println("reading"); } return byteBuffer.array(); } catch (IOException e) { e.printStackTrace(); throw e; } finally { try { channel.close(); } catch (IOException e) { e.printStackTrace(); } try { fs.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 下載excel檔案 * @param response * @param filePath * @param fileName:帶有後綴名的檔名 例如 a.xls * @throws Exception */ public static void downloadExcelFile(HttpServletResponse response, String filePath, String fileName) throws Exception { BufferedInputStream bis = null; BufferedOutputStream bos = null; try { // 設定response引數,可以開啟下載頁面 response.reset(); response.setContentType("application/vnd.ms-excel;charset=utf-8"); response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName).getBytes(), "iso-8859-1")); ServletOutputStream out = response.getOutputStream(); bis = new BufferedInputStream(new FileInputStream(filePath)); bos = new BufferedOutputStream(out); byte[] buff = new byte[2048]; int bytesRead; // Simple read/write loop. while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) { bos.write(buff, 0, bytesRead); } } catch (IOException e) { throw e; } finally { if (bis != null) bis.close(); if (bos != null) bos.close(); } } public static void downloadExcelFile(HttpServletResponse response, String fileName, byte[] fileContent) throws Exception { BufferedOutputStream bos = null; try { // 設定response引數,可以開啟下載頁面 response.reset(); response.setContentType("application/vnd.ms-excel;charset=utf-8"); response.setHeader("Content-Disposition", "attachment;filename=" + new String((fileName).getBytes(), "iso-8859-1")); ServletOutputStream out = response.getOutputStream(); bos = new BufferedOutputStream(out); if(null != fileContent){ bos.write(fileContent); } } catch (IOException e) { throw e; } finally { if (bos != null) bos.close(); } } /** * 將檔案轉成base64 字串 * @param path檔案路徑 * @return * * @throws Exception */ public static String encodeBase64File(String path) throws Exception { File file = new File(path); FileInputStream inputFile = new FileInputStream(file); byte[] buffer = new byte[(int) file.length()]; inputFile.read(buffer); inputFile.close(); return new BASE64Encoder().encode(buffer); } public static String encodeBase64File(MultipartFile file) throws Exception { return new BASE64Encoder().encode(file.getBytes()); } public static byte[] decoderBase64File(String base64Code) throws Exception { return new BASE64Decoder().decodeBuffer(base64Code); } /** * 將base64字元解碼儲存檔案 * @param base64Code * @param targetPath * @throws Exception */ public static void decoderBase64File(String base64Code, String targetPath) throws Exception { byte[] buffer = new BASE64Decoder().decodeBuffer(base64Code); FileOutputStream out = new FileOutputStream(targetPath); out.write(buffer); out.close(); } /** * 將base64字元儲存文字檔案 * @param base64Code * @param targetPath * @throws Exception */ public static void toFile(String base64Code, String targetPath) throws Exception { byte[] buffer = base64Code.getBytes(); FileOutputStream out = new FileOutputStream(targetPath); out.write(buffer); out.close(); } public static void main(String[] args) { try { String base64Code = encodeBase64File("E:\\test\\test1.xls"); System.out.println(base64Code); decoderBase64File(base64Code, "E:\\test\\test.xls"); // toFile(base64Code, "D:\\three.txt"); } catch (Exception e) { e.printStackTrace(); } } }