一.需要有jacob的jar包支持
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 }