一:通用文件上传功能
/*上传资源文件 upload */
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public Message upload(@RequestParam("file") MultipartFile file,HttpServletRequest request) {
//1
String originalFilename = file.getOriginalFilename();
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
//2 资源存储本地的绝对路径文件夹 usr.dir/upload/file/日期(yyyyMMdd格式)
String filePath = System.getProperty("user.dir") + "/" + "upload" + "/" + "file" + "/" + sdf.format(date) + "/";
//3
Dir = new File(filePath);
if (!Dir.exists()) {
Dir.mkdir();
}
//本地完整路径加文件名
File dest = new File(filePath + resParam.getFilename());
try {
//4 文件在本地进行下载存储
file.transferTo(dest);
} catch (Exception e) {
e.printStackTrace();
}
}
二:JacobUtil 工具 上传的(excel,word,ppt)文档转pdf后再转多张图片
1,方法需要的jar maven地址
<dependencies>
<dependency>
<groupId>org.jcodec</groupId>
<artifactId>jcodec</artifactId>
<version>0.2.3</version>
</dependency>
<dependency>
<groupId>org.jcodec</groupId>
<artifactId>jcodec-javase</artifactId>
<version>0.2.3</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>jacob</groupId>
<artifactId>jacob</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${basedir}/lib/jacob.jar</systemPath>
</dependency>
<!-- word、excel、ppt转pdf -->
<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/fontbox -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>fontbox</artifactId>
<version>2.0.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/pdfbox -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.9</version>
</dependency>
</dependencies>
2,主方法,对上传的资源文件进行处理
/*上传资源文件 upload */
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public Message upload(@RequestParam("file") MultipartFile file,HttpServletRequest request) {
AddResourceParam resParam = new AddResourceParam();
String originalFilename = file.getOriginalFilename();
Date date = new Date();
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMddHHmmssSSS");
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
resParam.setOriginal(originalFilename);
resParam.setFilename(sdf2.format(date) +System.nanoTime() +originalFilename.substring(originalFilename.lastIndexOf(".")));
if (file.getContentType().indexOf("image") != -1) {
resParam.setFiletype(Constant.FILE_TYPE_IMAGE);
}
if (file.getContentType().indexOf("video") != -1) {
resParam.setFiletype(Constant.FILE_TYPE_VIDEO);
}
if (file.getContentType().indexOf("document") !=-1 || file.getContentType().indexOf("pdf")!= -1) {
resParam.setFiletype(Constant.FILE_TYPE_DOCUMENT);
}
if (file.getContentType().indexOf("audio") !=-1) {
resParam.setFiletype(Constant.FILE_TYPE_AUDIO);
}
String filePath = System.getProperty("user.dir") + "/" + "upload" + "/" + "file" + "/" + getCurrentAccount().getOrganization() + "/" + sdf.format(date) + "/";
//资源存储本地的绝对路径文件夹 usr.dir/upload/1(组织名)/日期(yyyyMMdd格式)
Dir = new File(filePath);
if (!Dir.exists()) {
Dir.mkdir();
}
File dest = new File(filePath + resParam.getFilename());
try {
//文件在本地进行下载存储 本地完整路径加文件名
file.transferTo(dest);
// Filepath 存入数据库的虚拟位置
resParam.setFilepath("/file/" + this.getCurrentAccount().getOrganization() + "/" + sdf.format(date) + "/" + resParam.getFilename());
Map<String, Object> map = null;
/*获取图片信息或者视频信息*/
if (file.getContentType().indexOf("image") != -1) {
//上传完毕后通过map 集合加 ImageIO.read(new FileInputStream(img)) 获取图片资源的长,宽,时长
map = MediaUtil.getImageInfo(dest);
}
if (file.getContentType().indexOf("video") != -1) {
map = MediaUtil.getVideoInfo(dest);
}
//获取音频信息
if (file.getContentType().indexOf("audio") != -1) {
map = MediaUtil.getAudioInfo(dest);
}
//视频
if (file.getContentType().indexOf("video") != -1) {
//获取视频第一帧的文件名(图片)
//上传视频存放地址
String videoPath = filePath + resParam.getFilename();
String imgPath = System.getProperty("user.dir") + "\\upload\\file\\images\\";
File img = new File(imgPath);
if (!img.exists()) {//如果没有这个目录,
img.mkdir();//就创建一个新的目录
}
//System.out.println(videoPath);
String videoImgPath = imgPath + sdf2.format(date) + ".jpg";
if (resourceService.processVideoImg(videoPath,map,videoImgPath)) {
//截取成功
resParam.setVideoImgPath(systemMessageService.getSystemUrl() + "/file/images/"+sdf2.format(date) + ".jpg");
}
}
if (file.getContentType().indexOf("document") !=-1 || file.getContentType().indexOf("pdf")!= -1){
map = MediaUtil.getDocumentInfo(dest);
resParam.setWidth((Integer) map.get("width"));
resParam.setHeight((Integer) map.get("height"));
resParam.setDuration((Integer) map.get("duration"));
List<String> document_jpg = new ArrayList<>();
File document_file = new File(System.getProperty("user.dir")+"\\upload\\file\\documents_jpg");
if(!document_file.exists() && !document_file.isDirectory()){
document_file.mkdir();
}
//获取项目绝对路径
String pdfPath = System.getProperty("user.dir")+"\\upload\\file\\documents_jpg\\";
String a = filePath;
String u = a + resParam.getFilename();
//判断文档类型,并对应处理
if(".docx".equals(resParam.getFilename().substring(resParam.getFilename().lastIndexOf(".")))){
jacobUtil.trans(u,pdfPath + sdf2.format(date) + ".pdf","word");
resParam.setDocumentpath(systemMessageService.getSystemUrl() + "/file/documents_jpg/"+sdf2.format(date) + ".pdf");
List<String> jpg = jacobUtil.pdf2png(pdfPath,sdf2.format(date),"jpg");
for (int i=0;i<jpg.size();i++){
document_jpg.add(systemMessageService.getSystemUrl() + "/file/documents_jpg/"+jpg.get(i));
}
resParam.setDocument_jpg(document_jpg.toString().trim());
}else if(".xlsx".equals(resParam.getFilename().substring(resParam.getFilename().lastIndexOf(".")))){
jacobUtil.trans(u,pdfPath + sdf2.format(date) + ".pdf","excel");
resParam.setDocumentpath(systemMessageService.getSystemUrl() + "/file/documents_jpg/"+sdf2.format(date) + ".pdf");
List<String> jpg = jacobUtil.pdf2png(pdfPath,sdf2.format(date),"jpg");
for (int i=0;i<jpg.size();i++){
document_jpg.add(systemMessageService.getSystemUrl() + "/file/documents_jpg/"+jpg.get(i));
}
resParam.setDocument_jpg(document_jpg.toString().trim());
}else if(".pptx".equals(resParam.getFilename().substring(resParam.getFilename().lastIndexOf(".")))){
jacobUtil.trans(u,pdfPath + sdf2.format(date) + ".pdf","ppt");
resParam.setDocumentpath(systemMessageService.getSystemUrl() + "/file/documents_jpg/"+sdf2.format(date) + ".pdf");
List<String> jpg = jacobUtil.pdf2png(pdfPath,sdf2.format(date),"jpg");
for (int i=0;i<jpg.size();i++){
document_jpg.add(systemMessageService.getSystemUrl() + "/file/documents_jpg/"+jpg.get(i));
}
resParam.setDocument_jpg(document_jpg.toString().trim());
}else if(".pdf".equals(resParam.getFilename().substring(resParam.getFilename().lastIndexOf(".")))){
pdfPath = System.getProperty("user.dir") +"\\upload\\file\\"+this.getCurrentAccount().getOrganization()+"\\"+sdf.format(date)+"\\";
resParam.setDocumentpath(systemMessageService.getSystemUrl() + "/file/" + this.getCurrentAccount().getOrganization() + "/" + sdf.format(date) + "/" + resParam.getFilename());
List<String> jpg = jacobUtil.pdf2png(pdfPath,resParam.getFilename().substring(0,resParam.getFilename().length()-4),"jpg");
for (int i=0;i<jpg.size();i++){
document_jpg.add(systemMessageService.getSystemUrl() + "/file/" + this.getCurrentAccount().getOrganization() + "/" + sdf.format(date) + "/" +jpg.get(i));
}
resParam.setDocument_jpg(document_jpg.toString().trim());
}
}
int n = resourceService.addResource(resParam);
} catch (Exception e) {
e.printStackTrace();
}
}
3,主方法中使用到的各种工具类
jacobUtil工具类
package com.unccr.ms.util;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @author zhaojihao
* @date 2020/10/9 15:35
*/
public class JacobUtil {
//计时
public static void trans(String filePath, String pdfPath,String type){
try {
long old = System.currentTimeMillis();
toPdf(filePath,pdfPath, type);
long now = System.currentTimeMillis();
} catch (Exception e) {
System.out.println("转换失败:" + filePath);
e.printStackTrace();
}
}
//转换
private static void toPdf(String filePath, String pdfPath,String type) {
if("word".equals(type)){
word2PDF(filePath,pdfPath);
}else if("excel".equals(type)){
excel2PDF(filePath,pdfPath);
}else if("ppt".equals(type)){
ppt2PDF(filePath,pdfPath);
}
}
private static void word2PDF(String inputFile, String pdfFile) {
ActiveXComponent app = new ActiveXComponent("Word.Application");
try {
app.setProperty("Visible", false);
Dispatch docs = app.getProperty("Documents").toDispatch();
Dispatch doc = Dispatch.call(docs, "Open", new Object[]{inputFile, false, true}).toDispatch();
Dispatch.call(doc, "ExportAsFixedFormat", new Object[]{pdfFile, 17});
Dispatch.call(doc, "Close", new Object[]{false});
} catch (Exception e) {
e.printStackTrace();
}finally {
app.invoke("Quit");
}
}
private static void excel2PDF(String inputFile, String pdfFile) {
ComThread.InitSTA(true);
ActiveXComponent app = new ActiveXComponent("Excel.Application");
try {
app.setProperty("Visible", false);
app.setProperty("AutomationSecurity", new Variant(3));
Dispatch excels = app.getProperty("Workbooks").toDispatch();
Dispatch excel = Dispatch.invoke(excels, "Open", 1, new Object[]{inputFile, new Variant(false), new Variant(false)}, new int[9]).toDispatch();
Dispatch.invoke(excel, "ExportAsFixedFormat", 1, new Object[]{new Variant(0), pdfFile, new Variant(0)}, new int[1]);
Dispatch.call(excel, "Close", new Object[]{false});
if (app != null) {
app.invoke("Quit", new Variant[0]);
app = null;
}
ComThread.Release();
} catch (Exception e) {
e.printStackTrace();
}finally {
app.invoke("Quit");
}
}
private static void ppt2PDF(String inputFile, String pdfFile) {
ActiveXComponent app = new ActiveXComponent("PowerPoint.Application");
try {
Dispatch ppts = app.getProperty("Presentations").toDispatch();
Dispatch ppt = Dispatch.call(ppts, "Open", new Object[]{inputFile, true, true, false}).toDispatch();
Dispatch.call(ppt, "SaveAs", new Object[]{pdfFile, 32});
Dispatch.call(ppt, "Close");
app.invoke("Quit");
} catch (Exception e) {
e.printStackTrace();
}finally {
app.invoke("Quit");
}
}
/*pdf转图片*/
public static List<String> pdf2png(String fileAddress, String filename, String type) {
long old = System.currentTimeMillis();
List<String> list = new ArrayList<>();
// 将pdf装图片 并且自定义图片得格式大小
File file = new File(fileAddress+"\\"+filename+".pdf");
if(!file.exists()) {
return list;
}else{
try {
PDDocument doc = PDDocument.load(file);
PDFRenderer renderer = new PDFRenderer(doc);
int pageCount = doc.getNumberOfPages();
for (int i = 0; i < pageCount; i++) {
BufferedImage image = renderer.renderImageWithDPI(i, 250);
// Windows native DPI
// BufferedImage srcImage = resize(image, 240, 240);
//产生缩略图(生成对应的路径的图片)
ImageIO.write(image, type, new File(fileAddress+"\\"+filename+"_"+(i+1)+"."+type));
list.add(filename+"_"+(i+1)+"."+type);
}
} catch (IOException e) {
e.printStackTrace();
}
long now = System.currentTimeMillis();
return list;
}
}
}
2,对应截取上传视频第一帧作为图片的方法
//截取视频第一帧图片的方法
// 视频下载资源位置 veido_path
// 第一帧截图准备放置的 位置 imgPath
public boolean processVideoImg(String veido_path, Map<String, Object> map,String imgPath) throws Exception{
File file = new File(veido_path);
if (!file.exists()) {
System.err.println("路径[" + veido_path + "]对应的视频文件不存在!");
return false;
}
List<String> commands = new java.util.ArrayList<String>();
commands.add("C:\\ffmpeg\\bin\\ffmpeg.exe");
commands.add("-i");
commands.add(veido_path);
commands.add(imgPath);
commands.add("-y");
commands.add("-f");//设定输出格式
commands.add("image2");
commands.add("-r");//设定帧 此处设为1帧
commands.add("1");
commands.add("-ss");
commands.add("1");// 这个参数是设置截取视频多少秒时的画面
// commands.add("-t");
// commands.add("0.001");
commands.add("-s");
commands.add(map.get("width")+"x"+ map.get("height"));
//System.out.println(commands.toString());
try {
ProcessBuilder builder = new ProcessBuilder();
builder.command(commands);
builder.start();
System.out.println("视频第一帧图片截取成功");
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
三: 【ffmpeg工具】 截取上传视频第一帧作为图片
不需要过多参数的截取方法
//截取视频第一帧图片的方法 2
// 视频下载资源位置 videoPath
// 第一帧截图准备放置的 位置 imgPath
@Override
public boolean processVideoImg9(String videoPath, String imgPath) throws Exception {
File file = new File(videoPath);
if (!file.exists()) {
System.err.println("路径[" + videoPath + "]对应的视频文件不存在!");
return false;
}
try {
// 0 0 1 960 540 ===> 00:00:01 第一秒 960*540 图片尺寸
ProcessBuilder processBuilder = new ProcessBuilder("C:\\ffmpeg\\bin\\ffmpeg.exe", "-y",
"-i", videoPath, "-vframes", "1", "-ss", 0 + ":" + 0
+ ":" + 1, "-f", "mjpeg", "-s", 960 + "*" + 540,
"-an", imgPath);
Process process = processBuilder.start();
InputStream stderr = process.getErrorStream();
InputStreamReader isr = new InputStreamReader(stderr);
BufferedReader br = new BufferedReader(isr);
while ((br.readLine()) != null);
process.waitFor();
if (br != null)
br.close();
if (isr != null)
isr.close();
if (stderr != null)
stderr.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
四:上传的excel表 转换为 对象集合
1, pom.xml
<dependencies>
<!-- 使用到alibaba.fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.59</version>
</dependency>
<!-- POI,excel解析内容相关 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk8</classifier>
</dependency>
</dependencies>
2,主方法
ExcelResolve excelResolve1 =new ExcelResolve();
ObjectMapper objectMapper = new ObjectMapper();
File f1 = new File("E:/zcompany_project/codes/unccr-ad/ms/upload/file/1/20211222/20251271600.xlsx");
try {
//是 com.alibaba.fastJson
JSONArray json = excelResolve1.readExcel(f1);
List list1 = JSONObject.parseObject(json.toString(), List.class);
for(int i=0;i<list1.size();i++) {
// Student 对应的属性,是在你excel 中对应的列名
Student student = JSONObject.parseObject(JSONObject.toJSONString(list1.get(i)), Student.class);
System.out.println(student);
}
} catch (Exception e) {
e.printStackTrace();
}
3,excel内容处理工具类 ExcelResolve.java
package com.unccr.ms.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import com.alibaba.fastjson.*;
import org.springframework.stereotype.Component;
import sun.applet.Main;
@Component
public class ExcelResolve {
public final String XLSX = ".xlsx";
public final String XLS=".xls";
/**
* 获取Excel文件(.xls和.xlsx都支持)
* @param file
* @return 解析excle后的Json数据
* @throws IOException
* @throws FileNotFoundException
* @throws InvalidFormatException
*/
public JSONArray readExcel(File file) throws Exception{
int res = checkFile(file);
if (res == 0) {
System.out.println("File not found");
}else if (res == 1) {
return readXLSX(file);
}else if (res == 2) {
return readXLS(file);
}
JSONArray array = new JSONArray();
return array;
}
/**
* 判断File文件的类型
* @param file 传入的文件
* @return 0-文件为空,1-XLSX文件,2-XLS文件,3-其他文件
*/
public int checkFile(File file){
if (file==null) {
return 0;
}
String flieName = file.getName();
if (flieName.endsWith(XLSX)) {
return 1;
}
if (flieName.endsWith(XLS)) {
return 2;
}
return 3;
}
/**
* 读取XLSX文件
* @param file
* @return
* @throws IOException
* @throws InvalidFormatException
*/
public JSONArray readXLSX(File file) throws InvalidFormatException, IOException{
Workbook book = new XSSFWorkbook(file);
Sheet sheet = book.getSheetAt(0);
return read(sheet, book);
}
/**
* 读取XLS文件
* @param file
* @return
* @throws IOException
* @throws FileNotFoundException
*/
public JSONArray readXLS(File file) throws FileNotFoundException, IOException{
POIFSFileSystem poifsFileSystem = new POIFSFileSystem(new FileInputStream(file));
Workbook book = new HSSFWorkbook(poifsFileSystem);
Sheet sheet = book.getSheetAt(0);
return read(sheet, book);
}
/**
* 解析数据
* @param sheet 表格sheet对象
* @param book 用于流关闭
* @return
* @throws IOException
*/
public JSONArray read(Sheet sheet,Workbook book) throws IOException{
int rowStart = sheet.getFirstRowNum(); // 首行下标
int rowEnd = sheet.getLastRowNum(); // 尾行下标
// 如果首行与尾行相同,表明只有一行,直接返回空数组
if (rowStart == rowEnd) {
book.close();
return new JSONArray();
}
// 获取第一行JSON对象键
Row firstRow = sheet.getRow(rowStart);
int cellStart = firstRow.getFirstCellNum();
int cellEnd = firstRow.getLastCellNum();
Map<Integer, String> keyMap = new HashMap<Integer, String>();
for (int j = cellStart; j < cellEnd; j++) {
keyMap.put(j,getValue(firstRow.getCell(j), rowStart, j, book, true));
}
// 获取每行JSON对象的值
JSONArray array = new JSONArray();
for(int i = rowStart+1; i <= rowEnd ; i++) {
Row eachRow = sheet.getRow(i);
JSONObject obj = new JSONObject();
StringBuffer sb = new StringBuffer();
for (int k = cellStart; k < cellEnd; k++) {
if (eachRow != null) {
String val = getValue(eachRow.getCell(k), i, k, book, false);
sb.append(val); // 所有数据添加到里面,用于判断该行是否为空
obj.put(keyMap.get(k),val);
}
}
if (sb.toString().length() > 0) {
array.add(obj);
}
}
book.close();
return array;
}
/**
* 获取每个单元格的数据
* @param cell 单元格对象
* @param rowNum 第几行
* @param index 该行第几个
* @param book 主要用于关闭流
* @param isKey 是否为键:true-是,false-不是。 如果解析Json键,值为空时报错;如果不是Json键,值为空不报错
* @return
* @throws IOException
*/
public String getValue(Cell cell,int rowNum,int index,Workbook book,boolean isKey) throws IOException{
// 空白或空
if (cell == null || cell.getCellType()==Cell.CELL_TYPE_BLANK ) {
if (isKey) {
book.close();
throw new NullPointerException(String.format("the key on row %s index %s is null ", ++rowNum,++index));
}else{
return "";
}
}
// 0. 数字 类型
if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
if (HSSFDateUtil.isCellDateFormatted(cell)) {
Date date = cell.getDateCellValue();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return df.format(date);
}
String val = cell.getNumericCellValue()+"";
val = val.toUpperCase();
if (val.contains("E")) {
val = val.split("E")[0].replace(".", "");
}
return val;
}
// 1. String类型
if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
String val = cell.getStringCellValue();
if (val == null || val.trim().length()==0) {
if (book != null) {
book.close();
}
return "";
}
return val.trim();
}
// 2. 公式 CELL_TYPE_FORMULA
if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
return cell.getStringCellValue();
}
// 4. 布尔值 CELL_TYPE_BOOLEAN
if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
return cell.getBooleanCellValue()+"";
}
// 5. 错误 CELL_TYPE_ERROR
return "";
}
}