目的
近期在學GJB 5000A和CMMI,裏邊涉及到大量的表單,手動整理太麻煩,打算藉助json將word表單自動化實現。
設計中想讓文檔與程序儘量分離,後期的變更儘量少變更代碼,僅通過改變json和WORD模板就實現自動化出具表單。
第一步先實現的是將json文件的內容填入word模板中,第一步實現後,後期只要實現不同的json文件與word模板就能出具相應額表單了。
思路
本軟件涉及的技術主要是利用填寫書籤的方式完成Word的讀寫,具體涉及的技術可以和博客http://www.cnblogs.com/eye-like/p/4121219.html 中的類似。
json的讀寫主要是利用了newtonsoft的json處理方法,主要應用的是Linq方式。如果利用SelectToken應該可以讓代碼進一步精簡,懶得改寫了。
主要思想是:
- 先讀取json文件中的template屬性,取得需要的模板
- 讀取WORD模板文件
- 遍歷word模板中的標籤,根據標籤名稱查找json文件中contents屬性中每個對象對應的該屬性,將屬性值填入到生成的word文檔
- 根據contents中的SaveAs屬性和主菜單中的outDicrectory屬性另存word文檔
- 退出文檔與程序
- 殺掉所有的word進程(缺少本步驟有時會報錯)
需要注意的是,Word引用的包Microsoft.Office.Interop.Word的屬性“嵌入式互操作類型”默認是“TRUE”,需要改成"False",否則編譯會出錯。
代碼
具體代碼如下所示:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Data;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Microsoft.Office.Interop.Word;
using Microsoft.Office;
using Microsoft.Office.Interop;
namespace inputoutput
{
class Program
{
public static void killWinWordProcess()
{
System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName("WINWORD");
foreach (System.Diagnostics.Process process in processes)
{
bool b = process.MainWindowTitle == "";
if (process.MainWindowTitle == "")
{
process.Kill();
}
}
}
static void Main(string[] args)
{
String dir = Environment.CurrentDirectory;
StreamReader file = null;
JObject oInputOutput = null;
Application app = null;
Document doc = null;
String inputFile = null;
if (args.Length == 0)
{
inputFile = "\\default.json";
}
else
{
inputFile = "\\"+args[0].ToString();
}
//打開對應的json文件
try
{
file = File.OpenText(dir + inputFile);
} catch (Exception e)
{
Console.WriteLine("打開json文件出錯!");
throw (e);
}
String strContent = file.ReadToEnd();
file.Close();
//解析json文件
try
{
oInputOutput = JObject.Parse(strContent);
} catch (Exception e)
{
Console.WriteLine("json解析(Parse)出錯!");
throw (e);
}
//打開word
app = new ApplicationClass();
Bookmark bm = null;
String outDot = null;
//讀取template項的內容
try
{
outDot = dir + oInputOutput["template"].ToString();
}
catch(Exception e)
{
Console.WriteLine(("json沒有定義template"));
throw (e);
}
//打開對應的模板,並將json內容複製到模板裏,最後按模板規定另存
JArray jry = null;
try
{
jry = (JArray)oInputOutput.SelectToken("contents");
}
catch(Exception e)
{
Console.WriteLine("json文件未定義contents!");
throw (e);
}
int billCnt = jry.Count;
for (int i = 0; i < billCnt; i++)
{
try
{
doc = app.Documents.Add(outDot); //Read json file's template
}
catch (Exception e)
{
Console.WriteLine(("Document打開Docx模板失敗!"));
throw (e);
}
for (int j = 0; j < doc.Bookmarks.Count; j++)
{
bm = doc.Bookmarks[j + 1]; //Attention: Bookmark starts at 1
try
{
bm.Range.Text = oInputOutput["contents"][i][bm.Name].ToString();
}
catch (Exception e)
{
Console.WriteLine(("json文件contents第" + (i + 1).ToString() + "項" + bm.Name.ToString() + "索引出錯!"));
throw (e);
}
}
//如果沒有輸出目錄,則建立一個
try
{
String strOutDir = dir + oInputOutput["outDirectory"].ToString();
if (!Directory.Exists(strOutDir))
{
Directory.CreateDirectory(strOutDir);
}
doc.SaveAs(strOutDir + oInputOutput["contents"][i]["saveAs"].ToString());
}
catch (Exception e)
{
Console.WriteLine(("json文件contents第" + (i + 1).ToString() + "項" + "缺少saveAs或outDirectory定義!"));
throw (e);
}
doc.Close();
}
app.Quit();
killWinWordProcess(); //殺死所有word進程,否則程序退出可能會報錯
Console.WriteLine("處理完畢!請按回車退出。");
Console.ReadLine();
return;
}
}
}