springboot 文件的上傳、下載與在線預覽

文件的上傳和下載都比較簡單,在線預覽比較複雜,針對不同類型的文件可能要進行不同的處理。

本文使用了 pdf.js 和 openoffice 兩種方法實現文件的預覽


pom.xml
上傳和下載都不需要添加什麼依賴,該文件中除了springboot本身的依賴就是在線預覽需要的依賴

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		
		<!--jodconverter 核心包 -->
		<!-- https://mvnrepository.com/artifact/org.jodconverter/jodconverter-core -->
		<dependency>
			<groupId>org.jodconverter</groupId>
			<artifactId>jodconverter-core</artifactId>
			<version>4.3.0</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.artofsolving.jodconverter/jodconverter-core -->
		<!-- 
		<dependency>
		    <groupId>org.artofsolving.jodconverter</groupId>
		    <artifactId>jodconverter-core</artifactId>
		    <version>3.0-beta-4</version>
		</dependency>
		 -->

		<!--springboot支持包,裏面包括了自動配置類 -->
		<!-- https://mvnrepository.com/artifact/org.jodconverter/jodconverter-spring-boot-starter -->
		<dependency>
		    <groupId>org.jodconverter</groupId>
		    <artifactId>jodconverter-spring-boot-starter</artifactId>
		    <version>4.3.0</version>
		</dependency>

		
		<!--jodconverter 本地支持包 -->
		<!-- https://mvnrepository.com/artifact/org.jodconverter/jodconverter-local -->
		<dependency>
			<groupId>org.jodconverter</groupId>
			<artifactId>jodconverter-local</artifactId>
			<version>4.3.0</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.6</version>
		</dependency>
	</dependencies>

fileTest.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h3>文件上傳</h3>
	<form action="/uploadFile" method="post" enctype="multipart/form-data">
		<input type="file" name="file"/><br/><br/>
		<input type="submit" value="提交">
	</form>
	<hr/>
	<form action="/uploadFiles" method="post" enctype="multipart/form-data">
		<input type="file" name="file"/><br/><br/>
		<input type="file" name="file"/><br/><br/>
		<input type="file" name="file"/><br/><br/>
		<input type="submit" value="提交">
	</form>
	<hr/>
	<h3>文件下載</h3>
	點擊下載<a href="/downFile">《下載測試》</a>
	<hr/>
	<h3>文件預覽</h3> <!-- 要測試預覽什麼類型的文件,在後臺手動調整 -->
	點擊預覽<a href="javascript:void();" onclick="viewFileOnline()">《預覽測試》</a>
</body>
<script type="text/javascript">
	function viewFileOnline(){
		window.open("/js/pdfjs/web/viewer.html?file=/preview");
	}
</script>
</html>

application.properties
主要是用來配置 openoffice ,在線預覽用的

如果沒有下載好 openoffice,最好把 openoffice 的配置註釋掉,要不然啓動項目時報錯


spring.mvc.view.prefix=/templates/
spring.mvc.view.suffix=.html

# openoffice 的配置
jodconverter.local.enabled=true
jodconverter.local.office-home=C:/Program Files (x86)/OpenOffice 4
jodconverter.local.max-tasks-per-process=100
jodconverter.local.port-numbers=8100

文件上傳

感覺文件上傳沒什麼好說的,獲取相關屬性存到數據庫就行了。

	/**
	 * 單文件上傳
	 * @param file
	 * @return
	 * @throws IOException 
	 */
    @PostMapping("/uploadFile")
    @ResponseBody
    public String uploadFile(@RequestParam("file") MultipartFile file) throws IOException {
        if (file.isEmpty()) {
            return "上傳失敗,請選擇文件";
        }

        String fileName = file.getOriginalFilename();
        System.out.println("originalFilename==" + fileName); // 文件名.文檔類型
        System.out.println("name==" + file.getName());// 獲取的是input中 name 的值
        System.out.println("size==" + file.getSize());// 文件大小,單位:B
        
        String filePath = "E:/temptest/";
        File dest = new File(filePath + fileName);
        try {
        	// 方式一
            file.transferTo(dest);
            // 方式二
            //IOUtils.copy(file.getInputStream(), new FileOutputStream(dest));
            LOGGER.info("上傳成功");
            return "上傳成功";
        } catch (IOException e) {
            LOGGER.error(e.toString(), e);
        }
        return "上傳失敗!";
    }
    
    /**
     * 多文件上傳
     * @param file
     * @return
     */
    @PostMapping("/uploadFiles")
    @ResponseBody
    public String uploadFiles(HttpServletRequest request) {
    	List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
        String filePath = "E:/temptest/";
        for (int i = 0; i < files.size(); i++) {
            MultipartFile file = files.get(i);
            if (file.isEmpty()) {
            	System.out.println("未找到附件。。。");
                System.out.println("上傳第" + (++i) + "個文件失敗");
                i--; // 需要判斷下一個附件是否可以進行上傳,把上一行+1的下標減回去
                continue;
            }
            String fileName = file.getOriginalFilename();

            File dest = new File(filePath + fileName);
            try {
                file.transferTo(dest);
                LOGGER.info("第" + (i + 1) + "個文件上傳成功");
            } catch (IOException e) {
                LOGGER.error(e.toString(), e);
                
                return "上傳第" + (++i) + "個文件失敗";
            }
        }

        return "上傳成功";
    }

文件下載

	/**
	 * 文件下載
	 * .doc .docx .pdf .xls .xlsx .jpg .png .gif .txt .js .css .html .java的文件均可下載成功
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	@RequestMapping("/downFile")
	public ResponseEntity<FileSystemResource> down()throws UnsupportedEncodingException{
		String uploadPath = "E:/testFile";
		String realimgurl=uploadPath+"/DemoOneApplication.java";
		//String realimgurl=uploadPath+"/scDoc/Self-service analysis tool _ user manual.doc";
		System.out.println(realimgurl);
		
        File file = new File(realimgurl);
        if (file == null){
            return null;
        }
        
        String suffixType =realimgurl.substring(realimgurl.lastIndexOf("."));
        String newfilename ="自定義文件名稱"+suffixType;
        
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Content-Disposition", "attachment; filename=" +  URLEncoder.encode(newfilename, "UTF-8"));
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
 
        return ResponseEntity
                .ok()
                .headers(headers)
                .contentLength(file.length())
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .body(new FileSystemResource(file));
		
	}

可以說我當時能想到的文件類型基本都試了個編,都能正常下載下來
在這裏插入圖片描述

在線預覽

pdf.js實現

該方法非常簡便,不過只能預覽 pdf 文件
pdf.js 下載地址:http://mozilla.github.io/pdf.js/
在這裏插入圖片描述

	/**
	 * pdf.js實現,只能預覽pdf
	 * @param request
	 * @param response
	 */
	@RequestMapping("/preview")
	public void pdfPreview(HttpServletRequest request, HttpServletResponse response) {
        //PDF文件地址
		File file = new File("E:/testFile/temp.pdf");
		if (file.exists()) {
			byte[] data = null;
			FileInputStream input=null;
			try {
				input= new FileInputStream(file);
				data = new byte[input.available()];
				input.read(data);
				response.getOutputStream().write(data);
			} catch (Exception e) {
				System.out.println("pdf文件處理異常:" + e);
			}finally{
				try {
					if(input!=null){
						input.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
openoffice實現

該方式可以把各種文檔轉換成 pdf 文件,然後進行預覽,使用該方法必須先安裝 openoffice 。下載地址:http://www.openoffice.org/download/index.html

測試該方法試了 .doc .docx .xlsx .xls .jpg .png .pdf 類型的文件,發現 .xls 和 .pdf類型的讀不出來,其他的均可轉換並查看。

後面對於 .pdf 的文件,我跳過轉換步驟,把源文件直接當做送到前端的輸入流,即可成功預覽。所以,在應用過程中,應當是要獲取源文件的文件類型的,要分類處理並保存到數據庫

我是在 windows 測試的,安裝好 openoffice,沒有特意到 cmd 中啓動它,在這個項目啓動時,我發現會自動啓動 openoffice

	// 注入轉換器
    @Autowired
    private DocumentConverter converter;

    @Autowired
    private HttpServletResponse response;

    @RequestMapping("/viewByPDF")
    public void viewByPDF() {
		File file = new File("E:/testFile/yue.jpg");//需要轉換的文件
		try {
		    File newFile = new File("E:/prePDF");//轉換之後文件生成的地址
		    if (!newFile.exists()) {
		    	newFile.mkdirs();
		    }
		    //文件轉化
		    converter.convert(file).to(new File("E:/prePDF/view.pdf")).execute();
		    //使用response,將pdf文件以流的方式發送的前端
		    ServletOutputStream outputStream = response.getOutputStream();
		    InputStream in = new FileInputStream(new File("E:/prePDF/view.pdf"));// 讀取文件
		    // 如果源文件就是 pdf,不要轉換
		    //InputStream in = new FileInputStream(new File("E:/testFile/temp.pdf"));// 讀取文件
		    // copy文件
		    int i = IOUtils.copy(in, outputStream);
		    System.out.println(i);
		    in.close();
		    outputStream.close();
		} catch (Exception e) {
		    e.printStackTrace();
		}
		
    }

在這裏插入圖片描述

由於在某些瀏覽器,如 IE ,點擊預覽時會提示下載,一些類型的文件起不到預覽的作用,因此,可以利用 openoffice 先把文件轉換爲pdf,然後用 pdf.js 的方法進行預覽

對於在線預覽功能,我發現有篇博客考慮得很周全,寫得很細緻,可以參考一下 >>> https://blog.csdn.net/ccc1234_/article/details/79052809

本篇博客代碼已上傳 github >>> https://github.com/YOUflyme/demo_file

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章