laoliuya 发表于 2014-08-31 17:47

jacob循环替换模板文本的问题

RT,用以下程序按模板生成新的word,执行是可行的,但是现在需要循环替换模板文件,生成在同一个word上,则不行,只能执行一次,为何?应该如何修改?求高手指点。
模板已传到附件中package com.word;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.HashMap;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

public class Java2Word1 {
        private boolean saveOnExit;
        /**
       * word文档
       */
        private Dispatch doc = null;
        /**
       * word运行程序对象
       */
        private ActiveXComponent word;
        /**
       * 所有word文档
       */
        private Dispatch documents;

        /**
       * 构造函数
       */
        public Java2Word1() {
                saveOnExit = false;
                word = new ActiveXComponent("Word.Application");
                word.setProperty("Visible", new Variant(false));
                documents = word.getProperty("Documents").toDispatch();
        }

        /**
       * 设置参数:退出时是否保存
       *
       * @param saveOnExit
       *            true-退出时保存文件,false-退出时不保存文件
       */
        public void setSaveOnExit(boolean saveOnExit) {
                this.saveOnExit = saveOnExit;
        }

        /**
       * 得到参数:退出时是否保存
       *
       * @return boolean true-退出时保存文件,false-退出时不保存文件
       */
        public boolean getSaveOnExit() {
                return saveOnExit;
        }

        /**
       * 打开文件
       *
       * @param inputDoc
       *            要打开的文件,全路径
       * @return Dispatch 打开的文件
       */
        public Dispatch open(String inputDoc) {
                return Dispatch.call(documents, "Open", inputDoc).toDispatch();
        }

        /**
       * 选定内容
       *
       * @return Dispatch 选定的范围或插入点
       */
        public Dispatch select() {
                return word.getProperty("Selection").toDispatch();
        }

        /**
       * 把选定内容或插入点向上移动
       *
       * @param selection
       *            要移动的内容
       * @param count
       *            移动的距离
       */
        public void moveUp(Dispatch selection, int count) {
                for (int i = 0; i < count; i++)
                        Dispatch.call(selection, "MoveUp");
        }

        /**
       * 把选定内容或插入点向下移动
       *
       * @param selection
       *            要移动的内容
       * @param count
       *            移动的距离
       */
        public void moveDown(Dispatch selection, int count) {
                for (int i = 0; i < count; i++)
                        Dispatch.call(selection, "MoveDown");
        }

        /**
       * 把选定内容或插入点向左移动
       *
       * @param selection
       *            要移动的内容
       * @param count
       *            移动的距离
       */
        public void moveLeft(Dispatch selection, int count) {
                for (int i = 0; i < count; i++)
                        Dispatch.call(selection, "MoveLeft");
        }

        /**
       * 把选定内容或插入点向右移动
       *
       * @param selection
       *            要移动的内容
       * @param count
       *            移动的距离
       */
        public void moveRight(Dispatch selection, int count) {
                for (int i = 0; i < count; i++)
                        Dispatch.call(selection, "MoveRight");
        }

        /**
       * 把插入点移动到文件首位置
       *
       * @param selection
       *            插入点
       */
        public void moveStart(Dispatch selection) {
                Dispatch.call(selection, "HomeKey", new Variant(6));
        }

        /**
       * 从选定内容或插入点开始查找文本
       *
       * @param selection
       *            选定内容
       * @param toFindText
       *            要查找的文本
       * @return boolean true-查找到并选中该文本,false-未查找到文本
       */
        public boolean find(Dispatch selection, String toFindText) {
                // 从selection所在位置开始查询
                Dispatch find = Dispatch.call(selection, "Find").toDispatch();
                // 设置要查找的内容
                Dispatch.put(find, "Text", toFindText);
                // 向前查找
                Dispatch.put(find, "Forward", "True");
                // 设置格式
                Dispatch.put(find, "Format", "True");
                // 大小写匹配
                Dispatch.put(find, "MatchCase", "True");
                // 全字匹配
                Dispatch.put(find, "MatchWholeWord", "True");
                // 查找并选中
                return Dispatch.call(find, "Execute").getBoolean();
        }

        /**
       * 把选定内容替换为设定文本
       *
       * @param selection
       *            选定内容
       * @param newText
       *            替换为文本
       */
        public void replace(Dispatch selection, String newText) {
                // 设置替换文本
                Dispatch.put(selection, "Text", newText);
        }

        /**
       * 全局替换
       *
       * @param selection
       *            选定内容或起始插入点
       * @param oldText
       *            要替换的文本
       * @param newText
       *            替换为文本
       */
        public void replaceAll(Dispatch selection, String oldText, Object replaceObj) {
                // 移动到文件开头
                moveStart(selection);
                if (oldText.startsWith("table") || replaceObj instanceof List) {
                        replaceTable(selection, oldText, (List) replaceObj);
                } else {
                        String newText = (String) replaceObj;
                        if (oldText.indexOf("image") != -1
                                        || newText.lastIndexOf(".bmp") != -1
                                        || newText.lastIndexOf(".jpg") != -1
                                        || newText.lastIndexOf(".gif") != -1)
                                while (find(selection, oldText)) {
                                        replaceImage(selection, newText);
                                        Dispatch.call(selection, "MoveRight");
                                }
                        else
                                while (find(selection, oldText)) {
                                        replace(selection, newText);
                                        Dispatch.call(selection, "MoveRight");
                                }
                }
        }

        /**
       * 替换图片
       *
       * @param selection
       *            图片的插入点
       * @param imagePath
       *            图片文件(全路径)
       */
        public void replaceImage(Dispatch selection, String imagePath) {
                Dispatch.call(Dispatch.get(selection, "InLineShapes").toDispatch(),
                                "AddPicture", imagePath);
        }

        /**
       * 替换表格
       *
       * @param selection
       *            插入点
       * @param tableName
       *            表格名称,形如table$1@1、table$2@1...table$R@N,R代表从表格中的第N行开始填充,
       *            N代表word文件中的第N张表
       * @param fields
       *            表格中要替换的字段与数据的对应表
       */
        public void replaceTable(Dispatch selection, String tableName, List dataList) {
                if (dataList.size() <= 1) {
                        System.out.println("Empty table!");
                        return;
                }
                // 要填充的列
                String[] cols = (String[]) dataList.get(0);
                // 表格序号
                String tbIndex = tableName.substring(tableName.lastIndexOf("@") + 1);
                // 从第几行开始填充
                int fromRow = Integer.parseInt(tableName.substring(
                                tableName.lastIndexOf("$") + 1, tableName.lastIndexOf("@")));
                // 所有表格
                Dispatch tables = Dispatch.get(doc, "Tables").toDispatch();
                // 要填充的表格
                Dispatch table = Dispatch.call(tables, "Item", new Variant(tbIndex))
                                .toDispatch();
                // 表格的所有行
                Dispatch rows = Dispatch.get(table, "Rows").toDispatch();
                // 填充表格
                for (int i = 1; i < dataList.size(); i++) {
                        // 某一行数据
                        String[] datas = (String[]) dataList.get(i);
                        // 在表格中添加一行
                        if (Dispatch.get(rows, "Count").getInt() < fromRow + i - 1)
                                Dispatch.call(rows, "Add");
                        // 填充该行的相关列
                        for (int j = 0; j < datas.length; j++) {
                                // 得到单元格
                                Dispatch cell = Dispatch.call(table, "Cell",
                                                Integer.toString(fromRow + i - 1), cols)
                                                .toDispatch();
                                // 选中单元格
                                Dispatch.call(cell, "Select");
                                // 设置格式
                                Dispatch font = Dispatch.get(selection, "Font").toDispatch();
                                Dispatch.put(font, "Bold", "0");
                                Dispatch.put(font, "Italic", "0");
                                // 输入数据
                                Dispatch.put(selection, "Text", datas);
                        }
                }
        }

        /**
       * 保存文件
       *
       * @param outputPath
       *            输出文件(包含路径)
       */
        public void save(String outputPath) {
//                Dispatch.call((Dispatch) Dispatch.call(word, "WordBasic").getDispatch(),
//                          "FileSaveAs", outputPath,new Variant(51));
                Dispatch.invoke(doc, "SaveAs", Dispatch.Method,
                                new Object[] { outputPath }, new int);

        }

        /**
       * 关闭文件
       *
       * @param document
       *            要关闭的文件
       */
        public void close(Dispatch doc) {
                Dispatch.call(doc, "Close", new Variant(saveOnExit));
        }

        /**
       * 退出程序
       */
        public void quit() {
                word.invoke("Quit", new Variant);
                ComThread.Release();
        }

        /**
       * 根据模板、数据生成word文件
       *
       * @param inputPath
       *            模板文件(包含路径)
       * @param outPath
       *            输出文件(包含路径)
       * @param data
       *            数据包(包含要填充的字段、对应的数据)
       */
        public void toWord(String inputPath, String outPath, HashMap data) {
                String oldText;
                Object newValue;
                try {
                        doc = open(inputPath);
                        Dispatch selection = select();
                        Iterator keys = data.keySet().iterator();
                        while (keys.hasNext()) {
                                oldText = (String) keys.next();
                                newValue = data.get(oldText);
                                replaceAll(selection, oldText, newValue);
                        }
                        save(outPath);
                } catch (Exception e) {
                       //debug.println("toword------------操作word文件失败!"+e.getMessage(),true);
                        e.printStackTrace();
                }
                finally {
                        if (doc != null)
                                close(doc);
                }
        }
        public static void main(String[] args) {
               
                Java2Word1 j2w=new Java2Word1();
                String inputPath="C:\\Documents and Settings\\Administrator\\桌面\\报表\\提案模板.doc";
                String time = new SimpleDateFormat("yyyyMM-ddHHmmssSSS").format(new Date());
                String outPath="C:\\"+time+".doc";
                System.out.println(outPath);
                HashMap<String, String> data=new HashMap<String, String>();
                String main="社会发展.卫生.医疗";
                String settime="2013.12.17";
                String number="0004";
                String title="关于进一步完善社区卫生服务中心补充建立和配套医疗设施的提案";
                String zhuban="市卫生局";
                String huiban="市人力社保局";
                String content="问题:" +
                                "“看病贵、看病难”一直以来都是当今百姓最希望解决的问题。很多人都有过这样的经历:为了挂到大医院的专家号,早上天没亮就匆忙赶到医院开始排队等号……在大医院人满为患时,社区医院却“门可罗雀”。于是有了大医院里“病人等医生”,社区医院里“医生等病人”的反差。无论大病小患均到大医院就诊,已经成为百姓看病就医的习惯,“过度诊断”、“小病大治”也就应运而生,医患矛盾频发。" +
                                "中国的社区卫生服务是由以全科医生为核心的卫生服务团队提供的服务,相当于全科医疗服务,包括以个人的健康为中心的服务、以家庭为单位的服务、以社区为范围的服务和社会服务等内容。社区医院就是为百姓提供这种医疗服务的基层医院。" +
                                "在许多国家,社区医院都是就医首选,“小病在社区,大病到医院;手术在医院,护理在社区”已成医疗惯例。在英美等发达国家,基层卫生机构的就诊率达80%以上,不到20%的患者需转诊到中心医院或专科医院。在英国,平均每2000人就拥有一个社区全科医生。相比之下,我国的社区医疗就相形见绌了。调查显示,仅有22.5%的人愿意去社区医院就诊;而卫生部门的资料却表明,本来三级医院65%的门诊病人和77%的住院病人均可分流到社区卫生机构。究其原因,一方面是广大百姓对社区医院缺乏了解,另一方面,部分到社区医院就诊的患者反映:社区医院设备不足、就医条件差、人员资质水平有限、全科医生较少等诸多因素。" +
                                "按照国家对社区卫生服务中心规格的设定和服务任务要求按照1万名居民配备2-3名全科医生。公共卫生六位一体任务,即是指预防、医疗、保健、健康教育、康复和计划生育技术指导。目前社区卫生服务中心基本以区域建设完成,但就合理配套还有一定的差距。如大区域人口只有一个卫生服务中心,下属卫生站也不够,不能达到15分钟内步行到达。而且给当地社区卫生服务中心增加过多的医疗任务及公共卫生工作,造成社区卫生服务中心像个“筐”,什么都往里装,使得医务人员应接不暇,既完成不好绩效考核指标,又不能与正常的社区卫生服务中心同步争取“优秀”评比工作,大大挫伤了不是同一起跑线但是同一水平要求的一级社区卫生服务中心的积极性。\r\n" +
                                "分析:" +
                                "目前,全国95%的地级以上城市、86%的市辖区和一批县级市开展了城市社区卫生服务,全国已设置社区卫生服务中心3400多个社区卫生服务站近12000个,创建了108个全国社区卫生服务示范区。" +
                                "一个街道3万至10万常住居民规模设置一个社区卫生服务中心,居民从家中步行不超过15分钟能到达一个社区卫生服务机构。2000年我国60岁以上的老年人就已达到1.3亿,占我国总人口的10%,标明我国已经进入了老龄化社会。2020年预计我国60岁以上的老年人口将达到2.45亿,占总人口的16%以上。2020年基本实现城乡每万名居民有2-3名合格的全科医生,全国至少需要27万到41万名高素质的全科医生。而目前的全科医生和助理医生只有7.8万人,缺口近30万名。" +
                                "李克强总理说过:医改事关民生福祉,也是民心所向,坚持保基本、强基层、建机制,向深化改革要红利,把基本医疗卫生制度作为公共产品向全民提供。而基层医疗卫生机构是做好预防保健工作的“前哨”,深化医改要坚持预防为主、防治结合的方针,促进医疗卫生服务的关口要前移,重心下移。" +
                                "而就目前社区卫生服务中心机构而言,还存在诸多问题。如医疗人力资源匮乏、基础差、流失多等、是目前社区卫生服务面临的问题。要开展和完成真正意义上的“六位一体”工作尚有一定难度。\r\n" +
                                "建议:" +
                                "为了能更好的实现六位一体的服务模式,政府应继续加大投入与补偿政策,应进一步完善社区卫生服务机构结构建设,以便继续加强社区卫生服务“六位一体”功能:" +
                                "1、规范、严格按照国家规定的以区域人口建立、建设健全社区卫生服务中心、卫生站。" +
                                "2、统一完善各社区卫生服务中心配套设施、医疗科室建设。让老百姓享受规范的社区卫生服务中心服务要求。" +
                                "3、规范、完善健康档案及信息网络。" +
                                "4、绩效考核标准以管理人群为界定,让医务人员更实际、更好地完成各项医疗、公共卫生及医疗管理任务。" +
                                "5、加大对社区卫生服务中心的财力支持调整医疗保险相关政策:对社区卫生服务中心加大倾斜,完善配套政策;鼓励大医院办社区卫生服务中心,形成医疗集团牵头人,保障社区卫生服务医疗水平;鼓励民营资本进入社区卫生服务领域,共享医疗资源,进一步完善卫生机构内部运行机制:加强全科医师人才培养,推进社区卫生服务整体水平的提高,并广纳人才,以提高社区卫生服务中心的整体素质。" +
                                "";
                String person="王以新(189)";
                String job="首都医科大学附属北京安贞医院教育处副处长、全科医疗科主任";
                String address="北京市朝阳区安贞里首都医科大学附属北京安贞医院教育处";
                String cell="13910157217";
                String tel="64456417 64456417(Fax)";
                String post="100029";
                String email="Wangyixin6417@sina.com";
               
                        data.put("“主题词”", main);
                        data.put("“日期”", settime);
                        data.put("第“0”号", "第"+number+"号");
                        data.put("“主办”", zhuban);
                        data.put("“会办”", huiban);
                        data.put("“题目”", title);
                        data.put("“内容”", content);
                        data.put("“提案人”", person);
                        data.put("“职务”", job);
                        data.put("“联系地址”", address);
                        data.put("“联系手机”", cell);
                        data.put("“联系电话”", tel);
                        data.put("“邮政编码”", post);
                        data.put("“邮箱”", email);
                        Dispatch doc=j2w.open(inputPath);
          for(int i=0;i<3;i++)       
                  j2w.toWord(inputPath, outPath, data);

        }
}
页: [1]
查看完整版本: jacob循环替换模板文本的问题