1 import java.util.Iterator;
2 import java.util.List;
3 import java.util.HashMap;
4
5 import com.jacob.activeX.ActiveXComponent;
6 import com.jacob.com.ComThread;
7 import com.jacob.com.Dispatch;
8 import com.jacob.com.Variant;
9
10 public class WordUtil {
11 private boolean saveOnExit;
12
13 /**
14 * word文档
15 */
16 private Dispatch doc = null;
17
18 /**
19 * word运行程序对象
20 */
21 private ActiveXComponent word;
22
23 /**
24 * 所有word文档
25 */
26 private Dispatch documents;
27
28 /**
29 * 构造函数
30
31 */
32 public WordUtil() {
33 saveOnExit = false;
34 word = new ActiveXComponent("Word.Application");
35 word.setProperty("Visible", new Variant(false));
36 documents = word.getProperty("Documents").toDispatch();
37 }
38
39 /**
40 * 设置参数:退出时是否保存
41 * @param saveOnExit true-退出时保存文件,false-退出时不保存文件
42
43 */
44 public void setSaveOnExit(boolean saveOnExit) {
45 this.saveOnExit = saveOnExit;
46 }
47
48 /**
49 * 得到参数:退出时是否保存
50 * @return boolean true-退出时保存文件,false-退出时不保存文件
51
52 */
53 public boolean getSaveOnExit() {
54 return saveOnExit;
55 }
56
57 /**
58 * 打开文件
59 * @param inputDoc 要打开的文件,全路径
60
61 * @return Dispatch 打开的文件
62
63 */
64 public Dispatch open(String inputDoc) {
65 return Dispatch.call(documents, "Open", inputDoc).toDispatch();
66 }
67
68 /**
69 * 选定内容
70 * @return Dispatch 选定的范围或插入点
71
72 */
73 public Dispatch select() {
74 return word.getProperty("Selection").toDispatch();
75 }
76
77 /**
78 * 把选定内容或插入点向上移动
79 * @param selection 要移动的内容
80 * @param count 移动的距离
81
82 */
83 public void moveUp(Dispatch selection, int count) {
84 for (int i = 0; i < count; i++)
85 Dispatch.call(selection, "MoveUp");
86 }
87
88 /**
89 * 把选定内容或插入点向下移动
90 * @param selection 要移动的内容
91 * @param count 移动的距离
92
93 */
94 public void moveDown(Dispatch selection, int count) {
95 for (int i = 0; i < count; i++)
96 Dispatch.call(selection, "MoveDown");
97 }
98
99 /**
100 * 把选定内容或插入点向左移动
101 * @param selection 要移动的内容
102 * @param count 移动的距离
103
104 */
105 public void moveLeft(Dispatch selection, int count) {
106 for (int i = 0; i < count; i++)
107 Dispatch.call(selection, "MoveLeft");
108 }
109
110 /**
111 * 把选定内容或插入点向右移动
112 * @param selection 要移动的内容
113 * @param count 移动的距离
114
115 */
116 public void moveRight(Dispatch selection, int count) {
117 for (int i = 0; i < count; i++)
118 Dispatch.call(selection, "MoveRight");
119 }
120
121 /**
122 * 把插入点移动到文件首位置
123 * @param selection 插入点
124
125 */
126 public void moveStart(Dispatch selection) {
127 Dispatch.call(selection, "HomeKey", new Variant(6));
128 }
129
130 /**
131 * 从选定内容或插入点开始查找文本
132
133 * @param selection 选定内容
134 * @param toFindText 要查找的文本
135 * @return boolean true-查找到并选中该文本,false-未查找到文本
136 */
137 public boolean find(Dispatch selection, String toFindText) {
138 // 从selection所在位置开始查询
139
140 Dispatch find = Dispatch.call(selection, "Find").toDispatch();
141 // 设置要查找的内容
142 Dispatch.put(find, "Text", toFindText);
143 // 向前查找
144 Dispatch.put(find, "Forward", "True");
145 // 设置格式
146 Dispatch.put(find, "Format", "True");
147 // 大小写匹配
148
149 Dispatch.put(find, "MatchCase", "True");
150 // 全字匹配
151 Dispatch.put(find, "MatchWholeWord", "True");
152 // 查找并选中
153 return Dispatch.call(find, "Execute").getBoolean();
154 }
155
156 /**
157 * 把选定内容替换为设定文本
158
159 * @param selection 选定内容
160 * @param newText 替换为文本
161
162 */
163 public void replace(Dispatch selection, String newText) {
164 // 设置替换文本
165 Dispatch.put(selection, "Text", newText);
166 }
167
168 /**
169 * 全局替换
170 * @param selection 选定内容或起始插入点
171 * @param oldText 要替换的文本
172 * @param newText 替换为文本
173
174 */
175 public void replaceAll(Dispatch selection, String oldText, Object replaceObj) {
176 // 移动到文件开头
177
178 moveStart(selection);
179 if (oldText.startsWith("table") || replaceObj instanceof List) {
180 replaceTable(selection, oldText, (List) replaceObj);
181 } else {
182 String newText = (String) replaceObj;
183 if (oldText.indexOf("image") != -1
184 || newText.lastIndexOf(".bmp") != -1
185 || newText.lastIndexOf(".jpg") != -1
186 || newText.lastIndexOf(".gif") != -1)
187 while (find(selection, oldText)) {
188 replaceImage(selection, newText);
189 Dispatch.call(selection, "MoveRight");
190 }
191 else
192 while (find(selection, oldText)) {
193 replace(selection, newText);
194 Dispatch.call(selection, "MoveRight");
195 }
196 }
197 }
198
199 /**
200 * 替换图片
201 * @param selection 图片的插入点
202 * @param imagePath 图片文件(全路径)
203
204 */
205 public void replaceImage(Dispatch selection, String imagePath) {
206 Dispatch.call(Dispatch.get(selection, "InLineShapes").toDispatch(),
207 "AddPicture", imagePath);
208 }
209
210 /**
211 * 替换表格
212 * @param selection 插入点
213
214 * @param tableName 表格名称,形如table$1@1、table$2@1...table$R@N,R代表从表格中的第N行开始填充,
215 * N代表word文件中的第N张表
216 * @param fields 表格中要替换的字段与数据的对应表
217 */
218 public void replaceTable(Dispatch selection, String tableName, List dataList) {
219 if (dataList.size() <= 1) {
220 System.out.println("Empty table!");
221 return;
222 }
223 // 要填充的列
224
225 String[] cols = (String[]) dataList.get(0);
226 // 表格序号
227 String tbIndex = tableName.substring(tableName.lastIndexOf("@") + 1);
228 // 从第几行开始填充
229
230 int fromRow = Integer.parseInt(tableName.substring(tableName
231 .lastIndexOf("$") + 1, tableName.lastIndexOf("@")));
232 // 所有表格
233
234 Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
235 // 要填充的表格
236 Dispatch table = Dispatch.call(tables, "Item", new Variant(tbIndex))
237 .toDispatch();
238 // 表格的所有行
239 Dispatch rows = Dispatch.get(table, "Rows").toDispatch();
240 // 填充表格
241 for (int i = 1; i < dataList.size(); i++) {
242 // 某一行数据
243
244 String[] datas = (String[]) dataList.get(i);
245 // 在表格中添加一行
246
247 if (Dispatch.get(rows, "Count").getInt() < fromRow + i - 1)
248 Dispatch.call(rows, "Add");
249 // 填充该行的相关列
250 for (int j = 0; j < datas.length; j++) {
251 // 得到单元格
252
253 Dispatch cell = Dispatch.call(table, "Cell",
254 Integer.toString(fromRow + i - 1), cols[j])
255 .toDispatch();
256 // 选中单元格
257
258 Dispatch.call(cell, "Select");
259 // 设置格式
260 Dispatch font = Dispatch.get(selection, "Font").toDispatch();
261 Dispatch.put(font, "Bold", "0");
262 Dispatch.put(font, "Italic", "0");
263 // 输入数据
264 Dispatch.put(selection, "Text", datas[j]);
265 }
266 }
267 }
268
269 /**
270 * 保存文件
271 * @param outputPath 输出文件(包含路径)
272 */
273 public void save(String outputPath) {
274 Dispatch.call(Dispatch.call(word, "WordBasic").getDispatch(),
275 "FileSaveAs", outputPath);
276 }
277
278 /**
279 * 关闭文件
280 * @param document 要关闭的文件
281 */
282 public void close(Dispatch doc) {
283 Dispatch.call(doc, "Close", new Variant(saveOnExit));
284 }
285
286 /**
287 * 退出程序
288
289 */
290 public void quit() {
291 word.invoke("Quit", new Variant[0]);
292 ComThread.Release();
293 }
294
295 /**
296 * 根据模板、数据生成word文件
297 * @param inputPath 模板文件(包含路径)
298 * @param outPath 输出文件(包含路径)
299 * @param data 数据包(包含要填充的字段、对应的数据)
300
301 */
302 public void toWord(String inputPath, String outPath, HashMap data) {
303 String oldText;
304 Object newValue;
305 try {
306 doc = open(inputPath);
307 Dispatch selection = select();
308 Iterator keys = data.keySet().iterator();
309 while (keys.hasNext()) {
310 oldText = (String) keys.next();
311 newValue = data.get(oldText);
312 replaceAll(selection, oldText, newValue);
313 }
314 save(outPath);
315 } catch (Exception e) {
316 //debug.println("toword[Java2Word]------------操作word文件失败!"+e.getMessage(),true);
317
318 } finally {
319 if (doc != null)
320 close(doc);
321 }
322 }
323
324 public static void main(String[] args) {
325 HashMap<String,String> data = new HashMap<String,String>();
326 data.put("$id$", "chec-001");
327 data.put("$name$", "合同1");
328 data.put("$sort$", "土建");
329 data.put("$pay$", "15");
330 data.put("$total$", "30");
331 WordUtil wordUtil = new WordUtil();
332 wordUtil.toWord("D:\合同模板1.dot", "D:\合同1.doc", data);
333 wordUtil = null;
334 }
335 }