空閑時間無聊寫的一個軟著源代碼文檔生成器


一個java版本 掃描源代碼生成軟著文檔小項目

個人開發環境

java環境:Jdk1.8.0_60

編譯器:IntelliJ IDEA 2019.1

框架:Freemaker + Jacob + Java8

源代碼:https://gitee.com/YoCiyy/yoci-gen-doc-rz

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 = coreUtils.getFiles(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 = fileList.get(i);
			List<String> contentList = FileUtils.readLines(item, "UTF-8");
			for (String content : contentList) {
				// 替換xml無法識別的特殊字符
				content = content.trim().replaceAll("<", "").replaceAll(">", "").replaceAll("&", "");
				// 保證每一個模板字符不超過第二行
				if (content.length() > 65) {
					content = content.substring(0, 65);
				}
				// 跳過空行
				if (content.length() == 0) {
					continue;
				}
				// 跳過功能注釋 跳過版權注釋
				if (content.contains("/") || content.contains("*")) {
					continue;
				}
				// 填充模板字符串從 content1~content3000 保證每個模板3000行代碼
				dataMap.put("content" + lines, content);
				if (dataMap.size() == 3000) {
					// 生產doc
					coreUtils.genDoc(dataMap, OUT_PATH);
					System.out.println("生成第" + count + "份文檔");
					// 清理數據生成下一份
					dataMap.clear();
					count++;
					lines = 1;
					break;
				}
				lines++;
			}
		}
		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 (file.exists() && file.isDirectory()) {
				getFiles(file);
			} else {
				String filename = file.getName();
				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);
				}
			}
		}
		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 = configuration.getTemplate("tpl.ftl", "UTF-8");
			Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "UTF-8"));
			template.process(dataMap, out);
			out.close();
			// 將doc文檔轉換成docx
			coreUtils.convertDocxFmt(filePath1, filePath2, 1);
			outFile.delete();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 根據格式類型轉換 com.yociyy.rz.text.word 文件
	 *
	 * @param srcPath 源文件
	 * @param descPath 目標文件
	 * @param fmt 所轉格式
	 */
	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 = app.getProperty("Documents").toDispatch();
			// 打開Document進行另存為操作
			Dispatch doc = Dispatch.invoke(
					document,
					"Open",
					Dispatch.Method,
					new Object[] { file.getAbsolutePath(), 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();
		}
	}
}

pom.xml

<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.net.rar解壓,jacob-1.14.3-x64.dll放到本地安裝jdk bin目錄下即可)

1605012435238

第二步 v1.0版本一樣,修改目錄,直接啟動項目

1605013271402

第三步 查看生成結果

1605013549163

txtUtils v1.0

掃描源代碼生成txt文檔 v1.0版本,每一份大約3000行 60頁左右

直接修改路徑,啟動main方法即可

使用方式

1605012435238

源代碼

/**
 * 軟著文檔導出 導出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 = coreUtils.getFiles(f);
		long leftLines = 0;

		StringBuffer sb = new StringBuffer();

		for (int i = 0; i < fileList.size(); i++) {
			File item = fileList.get(i);
			List<String> contentList = FileUtils.readLines(item, "UTF-8");

			for (String content : contentList) {
				if (content.length() == 0) {
					continue;
				}
				// 跳過功能注釋 跳過版權注釋
				if (content.contains("/") || content.contains("*")) {
					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++;
			}
		}

	}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM