空闲时间⽆聊写的⼀个软著源代码⽂档⽣成器
⼀个java版本扫描源代码⽣成软著⽂档⼩项⽬
个⼈开发环境
java环境:Jdk1.8.0_60
编译器:IntelliJ IDEA 2019.1
框架:Freemaker + Jacob + Java8
docUtils v1.2
扫描源代码⽣成docx⽂档 v1.2版本,每⼀份3000⾏ 60页宋体五号 .docx源代码
⽣成流程
1、递归扫描指定源代码
2、通过将已经做好的docx模板,另存为xml⽂件,并修改xml⽂件为.ftl后缀的(freemaker)模板⽂件,(具体可以搜索freemaker⽣成word模板的⽅法)
3、将扫描的源代码填充⾄ftl模板⽂件,⽣成为doc源代码⽂档(本质其实还是xml⽂件,平均⼀份⼤约1.5M)
4、为了解决⽂档太⼤问题,采⽤jacob将doc(本质xml)转成docx后缀⽂件,最终⽂档⼀份50K左右
源代码
docUtils.java
/**
* 软著⽂档导出导出docx⽂档 3000⾏源代码 v1.2
*/
public class docUtils {
// 扫描的源代码
public static String PROJECT_URL = "D:\\javaDemo1\\text-boot";
// ⽂档输出路径
public static String OUT_PATH = "D:\\doc\\";
public static void main(String[] args) throws IOException {
File f = new File(PROJECT_URL);
List<File> fileList = Files(f);
long lines = 1;
long count = 1;
Map<String, Object> dataMap = new HashMap<String, Object>();
for (int i = 0; i < fileList.size(); i++) {
File item = (i);
List<String> contentList = adLines(item, "UTF-8");
for (String content : contentList) {
/
/ 替换xml⽆法识别的特殊字符
content = im().replaceAll("<", "").replaceAll(">", "").replaceAll("&", "");
// 保证每⼀个模板字符不超过第⼆⾏
if (content.length() > 65) {
content = content.substring(0, 65);
}
// 跳过空⾏
if (content.length() == 0) {
continue;
}
// 跳过功能注释跳过版权注释
if (ains("/") || ains("*")) {
continue;
}
// 填充模板字符串从 content1~content3000 保证每个模板3000⾏代码
dataMap.put("content" + lines, content);
if (dataMap.size() == 3000) {
// ⽣产doc
System.out.println("⽣成第" + count + "份⽂档");
// 清理数据⽣成下⼀份
dataMap.clear();
count++;
lines = 1;
break;
}
lines++;
}
}
System.out.println("⽂档已⽣成完成");
System.out.println("⽂档已⽣成完成");
}
}
coreUtils.java
public class coreUtils {
/**
* docx 格式
*/
private static final int DOCX_FMT = 12;
public static List<File> fileList = new ArrayList<File>();
/*
* 通过递归得到某⼀路径下所有的⽬录及其⽂件
*/
public static List<File> getFiles(File root) {
File[] files = root.listFiles();
for (File file : files) {
if (ists() && file.isDirectory()) {
getFiles(file);
} else {
String filename = Name();
String suffix = filename.substring(filename.lastIndexOf(".") + 1);
if (suffix.equals("java")) {
fileList.add(file);
System.out.println("addFile " + file);
} else {
System.out.println("notFile " + file);
}
}
}c语言编译器idea
return fileList;
}
public static void genDoc(Map<String, Object> dataMap, String outPath) {
// Map<String, Object> dataMap = new HashMap<String, Object>();
try {
// Configuration ⽤于读取ftl⽂件
Configuration configuration = new Configuration(new Version("2.3.0"));
configuration.setDefaultEncoding("UTF-8");
/**
* 以下是两种指定ftl⽂件所在⽬录路径的⽅式,注意这两种⽅式都是指定ftl⽂件所在⽬录的路径,⽽不是ftl⽂件的路径    */
// 指定路径的第⼀种⽅式(根据某个类的相对路径指定)
configuration.setClassForTemplateLoading(coreUtils.class, "/");
// 指定路径的第⼆种⽅式,我的路径是C:/a.ftl
// configuration.setDirectoryForTemplateLoading(new File("D:/"));
long name = System.currentTimeMillis();
// 输出⽂档路径及名称
String filePath1 = outPath + name + ".doc";
String filePath2 = outPath + name + ".docx";
File outFile = new File(filePath1);
// 以UTF-8的编码读取ftl⽂件
Template template = Template("tpl.ftl", "UTF-8");
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "UTF-8"));
template.process(dataMap, out);
out.close();
// 将doc⽂档转换成docx
outFile.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根据格式类型转换 t.word ⽂件
*
* @param srcPath 源⽂件
* @param descPath ⽬标⽂件
* @param fmt 所转格式
*/
public static void convertDocxFmt(String srcPath, String descPath, int fmt) throws Exception {
public static void convertDocxFmt(String srcPath, String descPath, int fmt) throws Exception {
File file = new File(srcPath);
// 实例化ComThread线程与ActiveXComponent
ComThread.InitSTA();
ActiveXComponent app = new ActiveXComponent("Word.Application");
try {
// ⽂档隐藏时进⾏应⽤操作
app.setProperty("Visible", new Variant(false));
// 实例化模板Document对象
Dispatch document = Property("Documents").toDispatch();
// 打开Document进⾏另存为操作
Dispatch doc = Dispatch.invoke(
document,
"Open",
Dispatch.Method,
new Object[] { AbsolutePath(), new Variant(false),
new Variant(true) },
new int[1]).toDispatch();
Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[] {
descPath, new Variant(DOCX_FMT) }, new int[1]);
Dispatch.call(doc, "Close", new Variant(false));
// return new File(descPath);
} catch (Exception e) {
throw e;
} finally {
// 释放线程与ActiveXComponent
app.invoke("Quit", new Variant[] {});
ComThread.Release();
}
}
}
<dependencies>
<!--Apache Commons-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.6</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>
<dependency>
<groupId>net.sf.jacob-project</groupId>
<artifactId>jacob</artifactId>
<version>1.14.3</version>
</dependency>
</dependencies>
使⽤⽅式(两步)
第⼀步:(也可直接搜索jacob安装⽅式/使⽤⽅式)
(jacob,是个强依赖的项⽬,需要将我放在项⽬resource 的jacob-1.14.3-x64_jb51.rar解压,jacob-1.14.3-x64.dll放到本地安装jdk bin⽬录下即可)
第⼆步 v1.0版本⼀样,修改⽬录,直接启动项⽬
第三步查看⽣成结果
txtUtils v1.0
扫描源代码⽣成txt⽂档 v1.0版本,每⼀份⼤约3000⾏ 60页左右
直接修改路径,启动main⽅法即可
使⽤⽅式
源代码
/**
* 软著⽂档导出导出txt⽂档⼤约3000⾏源代码 v1.0
*/
public class txtUtils {
// 扫描的源代码
public static String PROJECT_URL = "D:\\javaDemo1\\text-boot";
// ⽂档输出路径
public static String OUT_PATH = "D:\\doc\\";
public static void main(String[] args) throws IOException {
File f = new File(PROJECT_URL);
List<File> fileList = Files(f);
long leftLines = 0;
StringBuffer sb = new StringBuffer();
for (int i = 0; i < fileList.size(); i++) {
File item = (i);
List<String> contentList = adLines(item, "UTF-8");
for (String content : contentList) {
if (content.length() == 0) {
continue;
}
/
/ 跳过功能注释跳过版权注释
if (ains("/") || ains("*")) {
continue;
}
// 2950⾏⼤约3000页
if (leftLines > 2950) {
FileUtils.write(new File(OUT_PATH + System.currentTimeMillis() + ".txt"), sb.toString(), "UTF-8");    leftLines = 0;
sb.setLength(0);
break;
}
sb.append(content);
sb.append("\n");
leftLines++;
}
}
}
}