一、前言
这两周,我刚接触了Java设计模式,于是脑洞大开,想用Java写一个文件格式转换的小程序。一开始是只是随便写写,但是写着写着,发现不容易维护,于是就想用刚学习的静态工厂模式来完成文件格式转换。虽然静态工厂模式不属于GoF的23种经典设计模式,但是作为一个最容易上手,也是最容易体会面向对象设计的模式,用文件格式转换练练手,强化一下自己对静态工厂模式的认识和理解。
二、准备工作
Java编译器:Idea
所需jar包:aspose.pdf-11.8.0.jar、aspose.slides-19.3.jar、aspose.cells-8.5.2.jar、aspose.words-18.6-jdk16-crack.jar、commons-io-2.11.0.jar、fontbox-2.0.27.jar、java-1.0.2.jar、pdfbox-2.0.27.jar、Spire.Pdf.jar
所需配置文件:license.xml
所需jar包可从它们的官网获取:Spire相关包、aspose相关包、commons-io相关包、pdfbox相关包、fontbox相关包、java-1.0.2包
注:本博客只作为知识分享,切勿商用以上相关的jar包,否则后果自负。
三、绘制类图
在一开始拿到项目的时候,就开始编码是一个非常不好的习惯,我们应该学着分析项目,自然就可以从先画类图开始。
四、创建工程,编写代码
在项目跟路径下,创建一个lib文件夹,用于存放相关jar包。同时在src文件夹下,创建一个resources文件夹,用于存放配置文件。普通Java工程的resources文件夹创建较为特殊,以下是创建步骤:
- 先创建普通的文件夹,为其取名为resources。
- 找到File,选择Project Structure。
- 选择Modules,找到resources文件夹,单机鼠标右键,选择Sources。
- 最后选择Apply,然后ok即可。
- resources文件夹创建好后,接下来把配置文件放resources文件夹里。
- 根据类图,去创建相关的文件夹。
完成以上操作后,就可以根据上面的类图开始写代码了。 - 在type文件夹下,创建一个FileType的抽象类。
package com.YuGong.type;
import java.io.File;
import java.io.InputStream;
/**
* 抽象文件类型类
* 作者:Cool_foolisher
* 开始日期:2023-3-24
* 结束日期:2023-3-24
*/
public abstract class FileType {
protected InputStream fileInput; // 待处理的文件的路径
protected File outputFile; // 输出路径
public String oldFile; // 存储原文件路径
public String newFile; // 存储新文件路径
public String fileType; // 存储需要转换文件的类型名
public String userType; // 存储转换后类型的类型名(用户选择的文件类型)
protected double time; // 存储转换的时间
/**
* 文件类型转换的抽象方法
*/
public abstract void typeChange(String yFile, String xFile);
/**
* 获取License配置文件
* @return 是否获取成功 true:成功 false:失败
*/
protected abstract boolean getLicense();
}
- 然后再根据类图,在concreteType文件夹下,分别创建WordToPDF和PDFtoOther类。
package com.YuGong.concreteType;
import com.YuGong.type.FileType;
import com.YuGong.util.Method;
import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 文字转PDF类
* 作者:Cool_foolisher
* 开始日期:2023-3-24
* 结束日期:2023-3-24
*/
public class WordToPDF extends FileType {
/**
* 获取WordLicense配置文件
* @return 是否获取成功 true:成功 false:失败
*/
@Override
protected boolean getLicense() {
boolean result = false;
try {
File file = new File(String.valueOf(WordToPDF.class.getResource("/license.xml")));
License asposeLic = new License();
String s = Method.cutLongStr(file.getPath());
String value = new String(s.getBytes("utf-8"), "utf-8");
System.out.println("凭证文件的路径:" + value);
// 凭证文件的路径
asposeLic.setLicense(value);
result = true;
} catch (Exception e) {
System.out.println("获取Word凭证文件出现异常:");
e.printStackTrace();
}
return result;
}
/**
* 文字转PDF具体方法
* @param yFile 原文件的路径
* @param xFile 新文件的路径
*/
@Override
public void typeChange(String yFile, String xFile) {
// 验证License
if (!getLicense()) {
return;
}
FileOutputStream os = null;
String fileName = yFile.substring(yFile.lastIndexOf("\\")+1, yFile.lastIndexOf("."));
try {
long old = System.currentTimeMillis();
File file = new File(xFile + "\\" + fileName + userType); // 新建一个空白pdf文档
os = new FileOutputStream(file);
Document doc = new Document(yFile); // Address是将要被转化的word文档
// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
doc.save(os, SaveFormat.PDF);
System.out.println("原Word文件的路径:" + yFile);
System.out.println("新PDF文件的路径:" + file.getPath());
System.out.println("您把Word文件转换为PDF文件!!!");
System.out.println("文件正在转换...");
long now = System.currentTimeMillis();
int t1; // 用于存储将小数变成整数的时间
// 毫秒除以1000化成秒,秒除以60化成分,分 * 1000 取int 变成整数 赋值给 t1
t1 = (int) ((((now - old) / 1000.0) / 60) * 1000);
// t1在变成小数 除以 1000 变成 只有三位小数的时间 赋值给 time
time = (double) t1 / 1000;
System.out.println("共耗时:" + time + "分钟!!!");
} catch (Exception e) {
System.out.println("亲,您的word转PDF出现异常:");
e.printStackTrace();
}finally {
if (os != null) {
try {
os.flush();
os.close();
} catch (IOException e) {
System.out.println("亲,您的word转PDF结束出现异常:");
e.printStackTrace();
}
}
}
}
}
package com.YuGong.concreteType;
import com.YuGong.type.FileType;
import com.YuGong.util.Method;
import com.aspose.pdf.Document;
import com.aspose.pdf.License;
import com.aspose.pdf.SaveFormat;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
/**
* PDF转其他类(其他包括:Word、PPT、Excel)
* 作者:Cool_foolisher
* 开始日期:2023-3-24
* 结束日期:2023-3-24
*/
public class PDFToOther extends FileType {
/**
* 获取PDFLicense配置文件
* @return 是否获取成功 true:成功 false:失败
*/
@Override
protected boolean getLicense() {
boolean result = false;
String fileName = oldFile.substring(oldFile.lastIndexOf("\\")+1, oldFile.lastIndexOf("."));
try {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
File file = new File(String.valueOf(PDFToOther.class.getResource("/license.xml")));
String s = Method.cutLongStr(file.getPath());
String value = new String(s.getBytes("utf-8"), "utf-8");
// 凭证文件的路径
System.out.println("凭证文件的路径:" + value);
// 凭证文件的路径
InputStream license = Files.newInputStream(Paths.get(value));// 凭证文件
if (oldFile != null) {
System.out.println("原文件路径:" + oldFile);
fileInput = Files.newInputStream(Paths.get(oldFile));// 待处理的文件
}
System.out.println("新文件的保存路径:" + newFile);
outputFile = new File(newFile + "\\" + fileName + userType);// 输出路径
License asposeLic = new License();
asposeLic.setLicense(license);
license.close();
result = true;
} catch (Exception e) {
System.out.println("获取PDF凭证文件出现异常:");
e.printStackTrace();
}
return result;
}
/**
* PDF转其他具体方法
* @param yFile 原文件的类型
* @param xFile 新文件的类型
*/
@Override
public void typeChange(String yFile, String xFile) {
// 验证License
if (!getLicense()) {
return;
}
try {
long old = System.currentTimeMillis();
Document pdfDocument = new Document(fileInput);
OutputStream fileOutput = Files.newOutputStream(outputFile.toPath());
if (userType.equals(".docx")) {
pdfDocument.save(fileOutput, SaveFormat.DocX);
System.out.println("您把PDF文件转换为Word文件!!!");
System.out.println("文件正在转换...");
} else if (userType.equals(".doc")) {
pdfDocument.save(fileOutput, SaveFormat.Doc);
System.out.println("您把PDF文件转换为Word文件!!!");
System.out.println("文件正在转换...");
} else if (userType.equals(".xls") || userType.equals(".xlsx")) {
pdfDocument.save(fileOutput, SaveFormat.Excel);
System.out.println("您把PDF文件转换为Excel文件!!!");
System.out.println("文件正在转换...");
} else if (userType.equals(".ppt") || userType.equals(".pptx")) {
pdfDocument.save(fileOutput, SaveFormat.Pptx);
System.out.println("您把PDF文件转换为PPT文件!!!");
System.out.println("文件正在转换...");
}
fileOutput.close();
long now = System.currentTimeMillis();
int t1; // 用于存储将小数变成整数的时间
// 毫秒除以1000化成秒,秒除以60化成分,分 * 1000 取int 变成整数 赋值给 t1
t1 = (int) ((((now - old) / 1000.0) / 60) * 1000);
// t1在变成小数 除以 1000 变成 只有三位小数的时间 赋值给 time
time = (double) t1 / 1000;
System.out.println("共耗时:" + time + "分钟");
} catch (Exception e) {
System.out.println("亲,您的PDF转其他类型出现异常:");
e.printStackTrace();
}
}
}
- 接着,我们在factory文件夹下,创建一个FileTypeFactory工厂类。
package com.YuGong.factory;
import com.YuGong.concreteType.*;
import com.YuGong.type.FileType;
/**
* 文件类型转换简单工厂类
* 作者:Cool_foolisher
* 开始日期:2023-3-24
* 结束日期:2023-3-24
*/
public class FileTypeFactory {
public static FileType changeType(String oldType, String newType){
FileType fileType = null;
if ((".docx".equals(oldType) && ".pdf".equals(newType))
|| (".doc".equals(oldType) && ".pdf".equals(newType))
) {
fileType = new WordToPDF();
}
else if ((".pdf".equals(oldType))) {
fileType = new PDFToOther();
}
else {
System.out.println(oldType +"类型转换尚未开发!!!");
}
return fileType;
}
}
哈哈,这样我们的文件格式转换工厂的简单小程序就写好了,最后一步就是编写我们的测试类。在src下,创建一个Test测试类,来试试我们刚刚写好的小程序究竟能不能进行格式转换。
import com.YuGong.factory.FileTypeFactory;
import com.YuGong.type.FileType;
/**
* 文件类型转换的测试类
* 作者:Cool_foolisher
* 开始日期:2023-3-24
* 结束日期:2023-3-24
*/
public class Test {
public static void main(String[] args) {
String oldType; // 转换前类型
String newType; // 转换后类型
/*
Word转PDF的使用例子
*/
oldType = ".docx";
newType = ".pdf";
FileType wordToPDF = FileTypeFactory.changeType(oldType, newType);
wordToPDF.oldFile = "C:\\Users\\YuGong\\Desktop\\test.docx";
wordToPDF.newFile = "C:\\Users\\YuGong\\Desktop";
wordToPDF.userType = newType;
wordToPDF.typeChange(wordToPDF.oldFile, wordToPDF.newFile);
/*
PDF转Word的使用例子
*/
oldType = ".pdf";
newType = ".docx";
FileType pdfToOther = FileTypeFactory.changeType(oldType, newType);
pdfToOther.oldFile = "C:\\Users\\YuGong\\Desktop\\test.pdf";
pdfToOther.newFile = "C:\\Users\\YuGong\\Desktop";
pdfToOther.userType = newType;
pdfToOther.typeChange(pdfToOther.oldFile, pdfToOther.newFile);
}
}
测试文件可以用自己的文件哦!!!
五、结束语
到这里,大家可能会有一个疑问,这个项目明明引了这么多jar包,为什么却仅仅只能Word转PDF、PDF转其他(其他包括:Word、PPT、Excel)呢?原因很简单,其他类型文件之间的转换代码我没有写,😂😂😂~~~聪明的你,我相信,看到这里也一定可以自己去完善这个小程序了。给大家一点小提示,其实使用静态工厂模式来写项目时,我们在增加新功能的时候,不需要去改动原来的代码,只需要新建一个类即可,这也就满足我们面向对象设计原则的开闭原则,即:对扩展开放,对修改关闭。同时我们每一个具体类(如:PDFToOther)仅仅只实现一个功能,这也满足了单一职责原则。通过使用这些原则可以大大提高我们的软件结构的设计水平。
大家对于用静态工厂模式来写代码还有疑问,可以访问我的仓库,在认真的看一看!!!
如果觉得我的这篇文章对您有帮助,欢迎大家给我点赞,对于静态工厂模式任有疑问的话,欢迎大家在评论留言!!!本人也是刚刚学习编程的小菜鸟,文章如有写的不对的地方,也欢迎大佬的指正!!!