1. 程式人生 > >使用資料庫(mysql)欄位儲存檔案

使用資料庫(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();  
     
     }  
     
    }  
}