數據庫信息存儲為Excel,利用OSS進行文件上傳下載


ps:本篇文章的主要內容為從后端獲取數據,並將多條數據以Excel表格的方式存儲,並實現基於OSS的上傳和下載

主要知識

OSS對象存儲,EasyExcel 兩者都來自於阿里雲,請提前進行兩者的基礎知識學習

主要內容

1.實體類

實體類需要繼承BaseRowModel類,但目前這個類已被禁用,我還沒找到替代方式

@Data
public class User extends BaseRowModel {
    @ExcelProperty("編號")
    private int id;
    @ExcelProperty("姓名")
    private String name;
    @ExcelProperty("日期")
    private Date date;
    @ExcelProperty("內容")
    private String content;

}

這里可以用注解來設定Excel表格的表頭,同時官網有更多種自定義以及復雜表頭的設置,這里照例貼上官方文檔路徑
https://www.yuque.com/easyexcel/doc/easyexcel

2.Excel工具類

@Component
public class EasyExcelUtil<T extends BaseRowModel>{


    //生成一個讀取數據庫數據產生的excel字節文件
    //最普通的EasyExcel用法
    public ByteArrayOutputStream easyOut(List<T> list, Class<T> clazz) throws Exception{
        //上傳文件的命名規則,暫時沒寫
        //extension==.xlsx
        String extension = ExcelTypeEnum.XLSX.getValue();

        //建立一個字節數組輸出流,將excel文件的內容存入其中
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        /**
         *   這里指定用哪個class去寫,然后寫到第一個sheet,名字為模板,然后文件流會自動關閉
         *   這里可以定義表格的各種樣式
         *   out為字節流
         *   clazz為實體類的反射
         */
        EasyExcel.write(out, clazz).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("模板").doWrite(list);

        //System.out.println(ExcelTypeEnum.XLSX.getValue());
        return out;
    }
}

這里寫了一個非常基礎的工具方法,主要的核心代碼其實就一句

EasyExcel.write(out, clazz).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("模板").doWrite(list);

EasyExcel:一種最常用的工具類,主要提供了Write()方法
write() : 里面的參數,第一個為Excel表格寫入的目的地,目前總結兩種填法(更多填法請參考文檔)

  • 字符串:直接以字符串內容為名稱存儲在idea中
  • IO流 : 通常為輸出流,這個時候就可以選擇以輸入流的方式來存儲到本地或者遠程,比如OSS或者本地響應(responde.getOutPutStream)

registerWriteHandler:表格寬度自適應,這個不精確
sheet :這個方法也有很多傳參方式,主要是提供表格的頁數和頁名
image
doWrite :寫入的內容,比如一個以對象方式存儲了多條數據的list集合

3.OSS工具類

@Component
public class OSSClientUtil {

    // endpoint是訪問OSS的域名。如果您已經在OSS的控制台上 創建了Bucket,請在控制台上查看域名。
    // 如果您還沒有創建Bucket,endpoint選擇請參看文檔中心的“開發人員指南 > 基本概念 > 訪問域名”,
    // 鏈接地址是:https://help.aliyun.com/document_detail/oss/user_guide/oss_concept/endpoint.html?spm=5176.docoss/user_guide/endpoint_region
    // endpoint的格式形如“http://oss-cn-hangzhou.aliyuncs.com/”,注意http://后不帶bucket名稱,
    // 比如“http://bucket-name.oss-cn-hangzhou.aliyuncs.com”,是錯誤的endpoint,請去掉其中的“bucket-name”。
    private static String endpoint = "";

    // accessKeyId和accessKeySecret是OSS的訪問密鑰,您可以在控制台上創建和查看,
    // 創建和查看訪問密鑰的鏈接地址是:https://ak-console.aliyun.com/#/。
    // 注意:accessKeyId和accessKeySecret前后都沒有空格,從控制台復制時請檢查並去除多余的空格。
    private static String accessKeyId = "";//阿里雲注冊可得
    private static String accessKeySecret = "";//阿里雲注冊可得

    // Bucket用來管理所存儲Object的存儲空間,詳細描述請參看“開發人員指南 > 基本概念 > OSS基本概念介紹”。
    // Bucket命名規范如下:只能包括小寫字母,數字和短橫線(-),必須以小寫字母或者數字開頭,長度必須在3-63字節之間。
    private static String bucketName = "mytesto";

    // 生成OSSClient,您可以指定一些參數,詳見“SDK手冊 > Java-SDK > 初始化”,
    // 鏈接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/init.html?spm=5176.docoss/sdk/java-sdk/get-start
    OSS ossClient = null;
    public void fileUpload(ByteArrayOutputStream out){
        ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        //判斷桶名是否存在,如果不存在就新建一個
        //
        if (ossClient.doesBucketExist(bucketName)) {
            System.out.println("您已經創建Bucket:" + bucketName + "。");
        } else {
            System.out.println("您的Bucket不存在,創建Bucket:" + bucketName + "。");
            // 創建Bucket。詳細請參看“SDK手冊 > Java-SDK > 管理Bucket”。
            // 鏈接地址是:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/manage_bucket.html?spm=5176.docoss/sdk/java-sdk/init
            ossClient.createBucket(bucketName);
        }

        // 查看Bucket信息。詳細請參看“SDK手冊 > Java-SDK > 管理Bucket”。
        BucketInfo info = ossClient.getBucketInfo(bucketName);
        System.out.println("Bucket " + bucketName + "的信息如下:");
        System.out.println("\t數據中心:" + info.getBucket().getLocation());
        System.out.println("\t創建時間:" + info.getBucket().getCreationDate());
        System.out.println("\t用戶標志:" + info.getBucket().getOwner());

        //具體的文件上傳,獲取Excel文件的數據
        InputStream is = new ByteArrayInputStream(out.toByteArray());

        ossClient.putObject(bucketName, "456.xlsx", is);
        System.out.println("Object:" + "456.xlsx" + "存入OSS成功!!!");
        ossClient.shutdown();
    }


    //獲取可以下載的URL
    public String getDownURL(String fileName){

        ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        Date expiration = new Date(new Date().getTime() + 3600l * 1000);//過期時間設為1小時
        // 生成URL
        URL url = ossClient.generatePresignedUrl(bucketName, fileName, expiration);
        if (url != null) {
            return url.toString();
        }
        return null;

    }

這部分內容可見我的另一篇關於OSS對象存儲入門的博客,其內容基本相似

4.接口具體執行

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private EasyExcelUtil easyExcelUtil;

    @Autowired
    private OSSClientUtil ossClient;

    @GetMapping("/test")
    public void test() throws Exception {


        List<User> list = userService.findAll();

        //文件上傳到OSS
        ossClient.fileUpload(easyExcelUtil.easyOut(list,User.class));
        //根據這個文件的名字獲取下載鏈接,鏈接有效時長一小時
        String s = ossClient.getDownURL("456.xlsx");


        System.out.println("文件上傳成功!!!");
        System.out.println(s);
        //return s;
    }


}

這里加上一個簡單的本地下載的例子

 public void easyOutHttp(HttpServletResponse response, List<T> data, Class<T> clazz) throws Exception{
        try {
            String fileName = URLEncoder.encode("付款申請", "UTF-8");
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), clazz).autoCloseStream(Boolean.FALSE)
                    .sheet("sheet").doWrite(data);
        } catch (Exception e){
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = new HashMap<String, String>();
            map.put("status", "failure");
            map.put("message", "下載文件失敗" + e.getMessage());
            //response.getWriter().println(JSON.toJSONString(map));
        }

    }

這個方法與上面的Excel方法的唯一區別就是將生成的Excel表格數據以輸出流的方式寫入到response中,在訪問也買你時可以直接跳出下載窗口,同時也可以設計為在線打開,具體設置屬性如下
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
Content-disposition:這個屬性時能設置你寫入的內容是作為網頁的一部分或作為附件下載並且本地保存。更改后面的key
具體內容可以參考簡書博主的文章https://www.jianshu.com/p/d4a85d025768

以上完結。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM