最近接到一个任务,就是要用定时器定时转换office文件为pdf格式,图片文件为jpg格式,音频文件为mp3格式,视频文件为mp4格式,网上这类方法很多。我就按我现在写的已经实现了的方法来整理下,以后再与遇到类似的可以直接拷贝源码。
数据库表主要用到以下表:条目数据表(存放条目数据,其中含有电子件主表的id:file_main_id):***_hn;电子件主表(类似于索引,在条目数据与电子件明细表之间建立的,方便查询,其存放电子件地址file_path,条目数据表表名table_name):file_main;电子件明细表(,电子件名file_name,电子件大小file_size):file_detail;转换格式表(方便以后添加新的格式,原文件类型:original_type,目标文件类型:convert_type):file_format_relation。
- 代码如下:
直接上方法(此为引用类里面的方法):
/**
* 获取转换的文件数量
* @param webPath 项目路径
* @return 返回转换成功后的结果
*/
public int getFileConvertSum(String webPath) {
int er = 0;
String ffmpegPath = webPath + File.separator + "/player/";
List<Map<String, Object>> fileMainlist = getResultSet("select * from file_main where 1=1 and sort_id is not null and file_main_id ='803D5B3C-F3BC-0162-21E8-41D2EF8525E5'");
for (Map<String, Object> maiMap : fileMainlist) {
String fileMainId = (String) maiMap.get("file_main_id");
String filePath = (String) maiMap.get("file_path");
String sortId = (String) maiMap.get("sort_id");
String tableName =(String) maiMap.get("table_name");
if (StringUtils.isNotBlank(sortId)) {// 获取已归档明细表的数据
List<Map<String, Object>> fileDetailList = getResultSet("select a.* from file_detail a,"+tableName+" b where 1=1 and a.file_main_id=b.file_id and b.filing_state='已归档' and a.file_main_id ='"
+ fileMainId + "'");
for (Map<String, Object> detailMap : fileDetailList) {
String fileName = (String) detailMap.get("file_name");
String fileId = (String) detailMap.get("file_id");
String sourcePath = webPath + File.separator + filePath + File.separator + fileName;// 源文件
String sourceFileType = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();// 源文件文件类型
// 获取源文件格式及转换文件格式
List<Map<String, Object>> resultSet = getResultSet("SELECT * FROM file_format_relation WHERE original_type LIKE '%"
+ sourceFileType + "%'");
File file = new File(sourcePath);
if (file.isFile() && file.exists()) {
if (!resultSet.isEmpty()) {
String convertType = resultSet.get(0).get("convert_type").toString();// 目标文件类型
String targetPath = webPath+ File.separator + filePath+ File.separator
+ fileName.substring(0,fileName.lastIndexOf(".")) + "."+ convertType;// 目标文件
String newFileName = fileName.substring(0,fileName.lastIndexOf(".")) + "." + convertType;// 目标文件
String targetFolderPath = webPath + File.separator + filePath;// 目标文件夹
// 转换文件
if (StringUtils.isNotEmpty(convertType)) {
File targetFile = new File(targetPath);
File targetFolder = new File(targetFolderPath);
if (!targetFolder.exists()) {// 若目标文件夹不存在,创建目标文件夹
targetFolder.mkdirs();
} else if (targetFile.exists()) {// 若目标文件已存在,删除后重新转换源文件
targetFile.delete();
}
try {
System.out.println("开始转换" + sourcePath);
if (convertType.indexOf("pdf") > -1
&& ConvertPdfFile.toPdf(sourcePath,targetPath, sourceFileType)) {// 转换office文件
updateFile(fileId, targetPath,
newFileName);
er++;
} else if (convertType.indexOf("jpg") > -1
&& ConvertImgFile.ConvertImg(sourcePath, targetPath,sourceFileType)) {// 转换图片
updateFile(fileId, targetPath,
newFileName);
er++;
} else if (convertType.indexOf("mp3") > -1
&& ConvertMp3File.convertMp3(sourcePath, targetPath,sourceFileType)) {// 转换音频文件
updateFile(fileId, targetPath,
newFileName);
er++;
} else if (convertType.indexOf("mp4") > -1
&& ConvertMp4File.convertMp4(sourcePath, targetPath,ffmpegPath)) {// 转换视频文件
updateFile(fileId, targetPath,
newFileName);
er++;
} else {
System.out.println("转换失败,删除失败文件");
File failFile = new File(targetPath);
if (failFile.exists()) {
failFile.delete();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
} else {
System.out.println(sourcePath + "文件有问题,请确认!");
}
}
}
}
return er;
}
/**
* 更新明细表文件
* @param path
*/
private void updateFile(String fileId, String path, String newFileName) {
File file = new File(path);
DecimalFormat df = new DecimalFormat("0.00");// 保留小数点后两位
double fileSize = 0;
try {
if (file.exists()) {
fileSize = (double) ((double) new FileInputStream(file)
.available() / 1024 / 1024);
String unit = "MB";// 设置单位
if (fileSize < 1) {
fileSize = fileSize * 1024;
unit = "KB";
}
// 更新file_detail表
updateData("update file_detail set file_name ='" +
newFileName + "',file_size='"
+ df.format(fileSize)+unit + "' where file_id='" + fileId +
"'");
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String webPath = this.webPath;//项目路径
long old = System.currentTimeMillis();
ConvertFile cf =new ConvertFile();
int count =cf .getFileConvertSum(webPath);
long now =0;
if(count >0){
now = System.currentTimeMillis();
System.out.println("共转换了"+count+"个文件,耗时"+ ((now - old) / 1000.0) + "秒");
}
}
以下为转换office文件,图片文件,mp3文件,mp4文件的方法及类
转换office文件类(要部署一下license.xml文件,因为不同格式的office文件,license校验不一样,不然会有水印在转换后的文件上面
):
import java.io.*;
import com.aspose.cells.Workbook;
import com.aspose.cells.License;
import com.aspose.slides.Presentation;
import com.aspose.words.*;
public class ConvertPdfFile {
/**
* 校验license
* @param type 文件类型,不同类型的office文件,引入的license依赖包不一样,word与excel可共用依赖包,ppt不行,否则会出现水印
* @return
*/
private static boolean judgeLicense(String type) {
boolean result = false;
try {
// license.xml应放在../webapp/WEB-INF/classes路径下
InputStream is = ConvertPdfFile.class.getClassLoader()
.getResourceAsStream("license.xml");
if ("doc".equals(type) || "docx".equals(type) || "txt".equals(type)
|| "xls".equals(type)|| "xlsx".equals(type)) {
License aposeLic = new License();
aposeLic.setLicense(is);
} else if ("ppt".equals(type) || "pptx".equals(type)) {
com.aspose.slides.License aposeLic = new com.aspose.slides.License();
aposeLic.setLicense(is);
}
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 转换为pdf
* @param sourcePath 源文件路径
* @param targetPath 目标文件路径
* @param type 源文件类型
*/
public static boolean toPdf(String sourcePath, String targetPath,
String type) {
boolean tf = false;
File file = new File(targetPath);
if (!judgeLicense(type)) {
System.out.println("license错误");
tf = false;
} else if ("doc".equals(type) || "docx".equals(type)
|| "txt".equals(type)) {
if (wordofpdf(file, sourcePath)) {
tf = true;
}
} else if ("xlsx".equals(type) || "xls".equals(type)) {
if (excelOfPdf(file, sourcePath)) {
tf = true;
}
} else if ("ppt".equals(type) || "pptx".equals(type)) {
if (pptOfpdf(file, sourcePath)) {
tf = true;
}
} else {
System.out.println("暂不支持该类型:" + type);
}
return tf;
}
/**
* word转pdf
* @param file 文件
* @param sourcePath 输入路径
*/
private static boolean wordofpdf(File file, String sourcePath) {
boolean result = false;
FileOutputStream os = null;
Document doc;
try {
os = new FileOutputStream(file);
doc = new Document(sourcePath);
doc.save(os, com.aspose.words.SaveFormat.PDF);
result = true;
} catch (Exception e) {
e.printStackTrace();
System.out.println(sourcePath+"出问题");
result = false;
} finally {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println(sourcePath+"出问题");
result = false;
}
}
return result;
}
/**
* excel转pdf
* @param file 文件
* @param sourcePath 输入路径
*/
private static boolean excelOfPdf(File file, String sourcePath) {
boolean result = false;
FileOutputStream os = null;
try {
os = new FileOutputStream(file);
Workbook wb = new Workbook(sourcePath);
wb.save(os, com.aspose.cells.SaveFormat.PDF);
result = true;
} catch (Exception e) {
e.printStackTrace();
result = false;
} finally {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
result = false;
}
}
return result;
}
/**
* ppt转pdf
* @param file 文件
* @param sourcePath 输入路径
*/
private static boolean pptOfpdf(File file, String sourcePath) {
boolean result = false;
FileOutputStream os = null;
try {
os = new FileOutputStream(file);
Presentation pres = new Presentation(sourcePath);// 输入pdf路径
pres.save(os, com.aspose.slides.SaveFormat.Pdf);
result = true;
} catch (Exception e) {
e.printStackTrace();
result = false;
} finally {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
result = false;
}
}
return result;
}
}
转换图片文件类:
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ConvertImgFile {
/**
* 转换为jpg格式
* @param inputPath 源文件路径
* @param outputPath 目标文件路径
* @param type 源文件类型
*/
public static boolean ConvertImg(String inputPath, String outputPath,String type) {
boolean result = false;
if ("png".equals(type) || "bmp".equals(type) || "gif".equals(type)) {
BufferedImage bufferedImage;
try {
bufferedImage = ImageIO.read(new File(inputPath));
BufferedImage newBufferedImage = new BufferedImage(
bufferedImage.getWidth(), bufferedImage.getHeight(),
BufferedImage.TYPE_INT_RGB);
// TYPE_INT_RGB:创建一个RBG图像,24位深度,成功将32位图转化成24位
newBufferedImage.createGraphics().drawImage(bufferedImage, 0,
0, Color.WHITE, null);
ImageIO.write(newBufferedImage, "jpg", new File(outputPath));
result = true;
} catch (IOException e) {
e.printStackTrace();
result = false;
}
} else {
System.out.println("暂不支持该类型:" + type);
result = false;
}
return result;
}
}
转换mp3文件类:
import it.sauronsoftware.jave.AudioAttributes;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.EncoderProgressListener;
import it.sauronsoftware.jave.EncodingAttributes;
import it.sauronsoftware.jave.MultimediaInfo;
import java.io.File;
public class ConvertMp3File {
/**
* 转换成mp3格式
*
* @param sourcePath 源文件路径
* @param targetPath 目标文件路径
* @param sourceFileType 源文件类型
* @return
*/
public static boolean convertMp3(String sourcePath, String targetPath,
String sourceFileType) {
boolean tf = false;
File source = new File(sourcePath);// 源文件
File target = new File(targetPath);// 存放文件
ConvertMp3File cmf = new ConvertMp3File();
if (!sourceFileType.equals("mp3")) {
tf = cmf.ConvertToMp3(source, target);
tf = true;
}
return tf;
}
private boolean ConvertToMp3(File source, File target) {
ConvertProgressListener listener = new ConvertProgressListener();
boolean succeeded = true;
try {
// Audio Attributes/音频编码属性
AudioAttributes audio = new AudioAttributes();
/*
* 它设置将用于音频流转码的编解码器的名称。您必须从当前Encoder实例的getAudioEncoders()方法返回的列表中选择一个值
* 。否则, 您可以传递AudioAttributes.DIRECT_STREAM_COPY特殊值,该值需要源文件中原始音频流的副本。
*/
audio.setCodec("libmp3lame");
/*
* 它设置新重新编码的音频流的比特率值。如果未设置比特率值,编码器将选择默认值。该值应以每秒位数表示。例如,如果你想要128 kb /
* s比特率,你应该调用setBitRate(new Integer(128000))。
*/
audio.setBitRate(128000);
/* 它设置将在重新编码的音频流中使用的音频通道的数量(1 =单声道,2 =立体声)。如果未设置通道值,编码器将选择默认值。 */
audio.setChannels(2);
/*
* 它设置新重新编码的音频流的采样率。如果未设置采样率值,编码器将选择默认值。该值应以赫兹表示。例如,如果您想要类似CD的44100
* Hz采样率,则应调用setSamplingRate(new Integer(44100))。
*/
audio.setSamplingRate(44100);
/* 可以调用此方法来改变音频流的音量。值256表示没有音量变化。因此,小于256的值是音量减小,而大于256的值将增加音频流的音量。 */
audio.setVolume(new Integer(256));
// Encoding attributes/编码属性
EncodingAttributes attrs = new EncodingAttributes();
/*
* 它设置将用于新编码文件的流容器的格式。给定参数表示格式名称。
* 编码格式名称有效且仅在它出现在正在使用的Encoder实例的getSupportedEncodingFormats
* ()方法返回的列表中时才受支持。
*/
attrs.setFormat("mp3");
/*
* 它设置音频编码属性。如果从未调用过新的EncodingAttributes实例,或者给定参数为null,则编码文件中不会包含任何音频流
*/
attrs.setAudioAttributes(audio);
/*
* 它为转码操作设置偏移量。源文件将从其开始的偏移秒开始重新编码。例如,如果您想剪切源文件的前五秒,
* 则应在传递给编码器的EncodingAttributes对象上调用setOffset(5)。
*/
// attrs.setOffset(5F);
/*
* 它设置转码操作的持续时间。只有源的持续时间秒才会在目标文件中重新编码。例如,如果您想从源中提取和转码30秒的一部分,
* 则应在传递给编码器的EncodingAttributes对象上调用setDuration(30)
*/
// attrs.setDuration(30F);
// Encode/编码
Encoder encoder = new Encoder();
// encoder.encode(new MultimediaObject(source), target, attrs,
// listener);
encoder.encode(source, target, attrs, listener);
} catch (Exception ex) {
ex.printStackTrace();
succeeded = false;
}
return succeeded;
}
public class ConvertProgressListener implements EncoderProgressListener {
/*
* 编码器在分析源文件后调用此方法。该信息参数是实例
* ws.schild.jave.MultimediaInfo类,它代表了有关源音频和视频流及其容器的信息。
*/
public void sourceInfo(MultimediaInfo info) {
}
/*
* 每次完成编码操作的进度时,编码器调用该方法。所述permil参数是表示通过当前操作到达点的值和它的范围是从0(操作刚开始)到1000(操作完成
* )
*/
public void progress(int permil) {
double progress = permil / 1000.00;
// System.out.println(progress); //转码进度
}
/* 编码器调用该方法以通知关于代码转换操作的消息(通常消息是警告)。 */
public void message(String message) {
}
}
}
转换mp4格式类(要用到ffmpeg插件):
import java.util.ArrayList;
import java.util.List;
public class ConvertMp4File {
/**
* 转换为mp4格式
* @param sourcePath 源文件路径
* @param targetPath 目标文件路径
* @param ffmpegPath 转换器路径
* @return
*/
public static boolean convertMp4(String sourcePath,String targetPath,String ffmpegPath){
boolean tf =false;
List<String> command = new ArrayList<String>();
command.add(ffmpegPath + "ffmpeg");
command.add("-i");
command.add(sourcePath);
command.add("-c:v");
command.add("libx264");
command.add("-mbd");
command.add("0");
command.add("-c:a");
command.add("aac");
command.add("-strict");
command.add("-2");
command.add("-pix_fmt");
command.add("yuv420p");
command.add("-movflags");
command.add("faststart");
// command.add(outputPath + "a.mp4");
command.add(targetPath);
try {
// 方案1
// Process videoProcess = Runtime.getRuntime().exec(ffmpegPath +
// "ffmpeg -i " + oldfilepath
// + " -ab 56 -ar 22050 -qscale 8 -r 15 -s 600x500 "
// // + outputPath + "a.flv"); 哈哈
// + outputPath + fileName+ ".mp4");
// 方案2
Process videoProcess = new ProcessBuilder(command)
.redirectErrorStream(true).start();
new PrintStream(videoProcess.getErrorStream()).start();
new PrintStream(videoProcess.getInputStream()).start();
videoProcess.waitFor();
tf= true;
} catch (Exception e) {
e.printStackTrace();
tf = false;
}
return tf;
};
}
class PrintStream extends Thread {
java.io.InputStream __is = null;
public PrintStream(java.io.InputStream is) {
__is = is;
}
public void run() {
try {
while (this != null) {
int _ch = __is.read();
if (_ch != -1) {
// System.out.print((char) _ch);//此处注释掉,不然控制台会打印出转换内容
} else {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 下面的是引入jar包及license:
2.1.office文件转换及图片转换:
引入license.xml文件,在项目的WEB-INF/classes文件夹下面放入license.xml文件,如图:需要引入aspose包,存放到WEB-FIN/lib文件夹下面,如图:
- 2.mp3类引入jar包:
需要引入jave-1.0.2,也是存放在lib文件夹下面,如图:
2.3. mp4转换类没有需要引入的依赖包,而主要是需要引入ffmpeg这个转换插件,存放在项目的player文件夹,如图:
以上为4种常见类型的转换,其实这其中还可以转换成其它格式,看需求来,再测试。而我在项目跑起来的时候,tomcat在转换pdf文件时出现过GC溢出,在eclipse里面设置下,Windows-Prefereces-Tomcat-JVM Settings-Add设置下,完美解决。添加
-Xms1024M -Xmx2048M -XX:PermSize=128M -XX:MaxPermSize=256M
如图:
以上的依赖包都在我的资源里面可以下载到,或者可以在网上找最新的,主要是涉及到jave,aspose这2个依赖包