一.需要有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") != -1184 || newText.lastIndexOf(".bmp") != -1185 || newText.lastIndexOf(".jpg") != -1186 || newText.lastIndexOf(".gif") != -1)187 while (find(selection, oldText)) {188 replaceImage(selection, newText);189 Dispatch.call(selection, "MoveRight");190 }191 else192 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(tableName231 .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 HashMapdata = new HashMap ();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 }