在企业项目中,我们经常要做一些文件上传下载,以及pdf图文件的展示的功能,刚好今天有时间,写了和demo,来教大家如何实现这些功能
一、构建项目结构
首先按照下图,把整个项目的结构构架出来
二、导入依赖
必须导入对应依赖,不然会报错
<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>
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
</dependency>
<!--解析pdf文件-->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-tools</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>fontbox</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
三、在配置文件写好文件上传的路径
我们最好在配置文件里写文件上传的路径,这样以后改起来就很方便
server:
port: 8088
max-http-header-size: 1024
spring:
thymeleaf:
mode: LEGACYHTML5
cache: false
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd
filepath:
#测试
test: F:\workfile\test
#正式
pro: F:\workfile
四、写后端代码
在真实项目中,大部分的文件都是通过前端传递的参数来找到对应文件的路径,但是在这里,为了方便,我们把要下载的文件还有显示前端的pdf路径写死了
ViewController
package com.znb.controller;
import ch.qos.logback.core.util.FileUtil;
import com.znb.utils.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.Map;
@RestController
public class ViewController {
@Value("${filepath.test}")
private String filepath;
@Autowired
HttpServletRequest request;
@Autowired
HttpServletResponse response;
@PostMapping("/uploadPdf")
@ResponseBody
public String uploadPdf(MultipartFile file) throws Exception {
String pdfHref = FileUtils.getFileHref(filepath, "study",file);
File f = new File(pdfHref);
file.transferTo(f);
String originalFilename = file.getOriginalFilename();
System.out.println(pdfHref+"##"+originalFilename);
return pdfHref+"##"+originalFilename;
}
@RequestMapping("/showPdfImg")
@ResponseBody
public Map<String,Object> showPdf(String pdfUrl) throws IOException {
Map<String, Object> pdfImgs = FileUtils.getPdfImgs(request, pdfUrl);
return pdfImgs;
}
@RequestMapping("/downFile")
public String downtFile( ){
File file = new File("F:\\workfile\\test/study/08be3f1c28904e86a4418bf62d4fc7a6.pdf");
FileUtils.downloadFile(request,response,file);
return "";
}
}
ViewController
@Controller
public class ViewController {
@RequestMapping("/")
public String index(){
System.out.println("");
return "index";
}
}
五、前端代码
这里从网络上导入了jquery,大家记得加进去,如果你的项目里面有,那么记得删除
index
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<div class="col-sm-1">
<a href="javascript:;" class="file">上传
<input type="file" id="priceFile" onchange="uploadPriceFile()">
<span class="hidden" id="priceOk"></span>
</a>
<input type="hidden" id="contract_file_name" name="fileName">
<input type="hidden" id="price_file_name" name="priceFileName">
<a id="File" th:text="下载查看"></a>
<input type="submit" value="查看pdf" onclick="showPdf('F:\\workfile\\test/study/08be3f1c28904e86a4418bf62d4fc7a6.pdf')">
<div id="bankFlow" style="width: 70%"></div>
</div>
</body>
<script src="http://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
$("#File").attr("href","/downFile");
function uploadPriceFile() {
var fileObj = document.getElementById("priceFile").files[0]; // js 获取文件对象
if(fileObj!=null){
var form = new FormData(); // FormData 对象
form.append("file", fileObj); // 文件对象
$.ajax({
type : "post",
url : "/uploadPdf",
data : form,
dataType:"text",
processData:false,
contentType:false,
success : function(res) {
var split = res.split("##");
$("#priceOk").attr("class","fa fa-check");
$("#price_file_address").val(split[0]);
$("#price_file_name").val(split[1]);
$("#ticket_file").text(split[1]);
}
})
}
}
function showPdf(file) {
var html = '';
$.ajax({
url: "/showPdfImg",
data: {"pdfUrl": file},
type: "post",
async: false,
success: function (res) {
var ticketHrefArray = res.hrefArray;
if(ticketHrefArray){
for (var i = 0; i < ticketHrefArray.length; i++) {
html += '<tr align="center"><td><img src="' + ticketHrefArray[i] + ' " width="100%"></td></tr>';
}
}else{
layer.msg(res.msg)
}
}
})
document.getElementById('bankFlow').innerHTML = html;
return html;
}
</script>
</html>
六、工具类
FileUtils
package com.znb.utils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
public class FileUtils {
public static String getFileHref(String sourceHref, String folderName, MultipartFile file){
System.out.println(sourceHref);
System.out.println(folderName);
String originalFilename = file.getOriginalFilename();
String suffix=originalFilename.substring(originalFilename.lastIndexOf("."));
String savePath = sourceHref+"/"+folderName+"/"+ UUID.randomUUID().toString().replaceAll("-","")+suffix;
File href = new File(sourceHref+"uploadFiles/"+folderName+"/");
if(!href.exists()){
href.mkdir();
}
return savePath;
}
/**
* 解析pdf获取图片集合
* @param request
* @param pdfUrl
* @return
* @throws IOException
*/
public static Map<String,Object> getPdfImgs(HttpServletRequest request, String pdfUrl) throws IOException {
File file=new File(pdfUrl);
PDDocument load = PDDocument.load(file);
int size = load.getNumberOfPages();
PDFRenderer pdfRenderer = new PDFRenderer(load);
List<String> list=new ArrayList<>();
String random = UUID.randomUUID().toString();
for (int i = 0; i < size; i++) {
//生成图片
BufferedImage bufferedImage = pdfRenderer.renderImage(i,1.5f);
String realPath = request.getServletContext().getRealPath("/");
String ImgHref=realPath + "amsImg";
File f = new File(ImgHref);
if(!f.exists()){
f.mkdir();
}
String path=ImgHref+"/"+random+i+".jpg";
list.add("/amsImg/"+random+i+".jpg");
FileOutputStream fileOutputStream = new FileOutputStream(path);
ImageIO.write(bufferedImage,"png",fileOutputStream);
}
load.close();
Map<String,Object> map=new HashMap();
map.put("hrefArray",list);
return map;
}
/**
* 下载文件
* @param request
* @param response
* @param file
*/
public static void downloadFile(HttpServletRequest request,HttpServletResponse response, File file) {
BufferedInputStream bis = null;
InputStream is = null;
OutputStream os = null;
BufferedOutputStream bos = null;
try {
String fileName = file.getName();
is = new FileInputStream(file); //文件流的声明
os = response.getOutputStream(); //重点突出(特别注意),通过response获取的输出流,作为服务端向客户端浏览器输出内容的通道
// 为了提高效率使用缓冲区流
bis = new BufferedInputStream(is);
bos = new BufferedOutputStream(os);
// 处理下载文件名的乱码问题(根据浏览器的不同进行处理)
if (request.getHeader("User-Agent").toLowerCase().indexOf("firefox") > 0) {
fileName = new String(fileName.getBytes("GB2312"),"ISO-8859-1");
} else {
// 对文件名进行编码处理中文问题
fileName = java.net.URLEncoder.encode(fileName, "UTF-8");// 处理中文文件名的问题
fileName = new String(fileName.getBytes("UTF-8"), "GBK");// 处理中文文件名的问题
}
response.reset(); // 重点突出
response.setCharacterEncoding("UTF-8"); // 重点突出
response.setContentType("application/x-msdownload");// 不同类型的文件对应不同的MIME类型 // 重点突出
response.setHeader("Content-Disposition", "attachment;filename="+ fileName);// 重点突出
int bytesRead = 0;
byte[] buffer = new byte[4096];
while ((bytesRead = bis.read(buffer)) != -1){ //重点
bos.write(buffer, 0, bytesRead);// 将文件发送到客户端
bos.flush();
}
} catch (Exception ex) {
throw new RuntimeException(ex.getMessage());
} finally {
// 特别重要
// 1. 进行关闭是为了释放资源
// 2. 进行关闭会自动执行flush方法清空缓冲区内容
try {
if (null != bis) {
bis.close();
bis = null;
}
if (null != bos) {
bos.close();
bos = null;
}
if (null != is) {
is.close();
is = null;
}
if (null != os) {
os.close();
os = null;
}
} catch (Exception ex) {
throw new RuntimeException(ex.getMessage());
}
}
}
}
七、完成
如果喜欢请给个三连吧