目的
近期在学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;
}
}
}