jacob 给word加印的功能

花了两天时间,参考了一些资料,总算是处理好了这样一个技术点。

关键的心得如下:

使用jacob,重点不是jacob本身,而是office的一些API资料。比如需要知道光标的移动, 包括上下左右的move(MoveUp, MoveDown,MoveLeft, MoveRight),包括回到首页起点Dispatch.put(selection, "Start", 0)等等。

严格的说,这边并没有很系统化的去了解jacob的底层。但对于一些关键点,还是可以拿出来分享的。比如插入一张图片之后,系统可以拿到一个Dispatch对象(例如叫做obj),我们则需要调用Dispatch.call(obj,"select"),这样相当于使用鼠标在word选中了新插入的图片,而后我们就可以通过Dispatch得到图片的ShapeRange,进而得到ShapeRange的WrapFormat,再对WrapFormat进行设定。对应的结构可以归纳为:Image->ShapeRange->WrapFormat。但是要想知道WrapFormat对应到的是哪些值,且有哪些作用,则需要去查询MSDN。这边查询到的相关值如下:

wdWrapInline 7 将形状嵌入到文字中。
wdWrapNone 3 将形状放在文字前面。请参阅 wdWrapFront 。
wdWrapSquare 0 使文字环绕形状。行在形状的另一侧延续。
wdWrapThrough 2 使文字环绕形状。
wdWrapTight 1 使文字紧密地环绕形状。
wdWrapTopBottom 4 将文字放在形状的上方和下方。
wdWrapBehind 5 将形状放在文字后面。
wdWrapFront 6 将形状放在文字前面。

这种匈牙利命名法的变量名,其实都对应到一个整型数据(应该是一个常量型的变量)。比如这次代码中需要用到的将印章图片盖在文字的前面,对应到得变量是wdWrapFront,也就是数值6.

再有就是要知道传入的word文件共有几页,加印的话,应该是每一页都要盖章的,于是就需要通过Dispatch.call(cursor,"information",4)来获取,此时cursor(光标)可能是需要回到word首页的开始位置(还未测试)。然后的思路就是要将光标指定到某个位置并以在文字前面的方式插入印章图片,实现的方式是:光标遍历到每一页的开始位置,并在此基础上移动到当前页的显眼位置。在开发过程中,将光标移动到每一页的开始位置,是花了相当的时间的。MSDN上并没有给出很直观的例子,甚至还找到了此功能无法实现的文章。直到找到了一篇名为“delphi读取WORD文档每一页的内容”的帖子,并注意到里面使用的

  //定位到第i页
      PageRange := wordapp.Selection.GoTo(wdGoToPage, wdGoToNext, IntToStr(i)); //<---->再一次匈牙利命名法的变量

这种不太一样的写法正是对应到了

  Dispatch.invoke(this.cursor, "Goto", Dispatch.Method, new Object[] {1, 2, String.valueOf(index)}, new int[1]);//<---->匈牙利命名法的变量对应到的整型常量,参考语句出处

以下是完整的Java代码,要正确使用的话,需要将jacob的jar包放进工程,并在运行环境中加入jacob.dll。

  1 import com.jacob.activeX.ActiveXComponent;
  2 import com.jacob.com.Dispatch;
  3 import com.jacob.com.Variant;
  4 import com.jacob.com.ComThread;
  5 
  6 public class WordInsertPicture {
  7 
  8  public WordInsertPicture() {
  9  }
 10 
 11  // 声明一个静态的类实例化对象
 12  private static WordInsertPicture instance;
 13  // 声明word文档对象
 14  private Dispatch doc = null;
 15  // 声明word文档当前活动视窗对象
 16  private Dispatch activeWindow = null;
 17  // 声明word文档选定区域或插入点对象
 18  private Dispatch docSelection = null;
 19  // 声明所有word文档集合对象
 20  private Dispatch wrdDocs = null;
 21  // 声明word文档名称对象
 22  private String fileName;
 23  // 声明ActiveX组件对象:word.Application,Excel.Application,Powerpoint.Application等等
 24  private ActiveXComponent wrdCom;
 25 
 26  /**
 27   * 获取Word操作静态实例对象
 28   * 
 29   * @return 报表汇总业务操作
 30   */
 31  public final static synchronized WordInsertPicture getInstance() {
 32   if (instance == null)
 33    instance = new WordInsertPicture();
 34   return instance;
 35  }
 36 
 37  /**
 38   * 初始化Word对象
 39   * 
 40   * @return 是否初始化成功
 41   */
 42  public boolean initWordObj() {
 43   boolean retFlag = false;
 44   ComThread.InitSTA();// 初始化com的线程,非常重要!!使用结束后要调用 realease方法
 45   wrdCom = new ActiveXComponent("Word.Application");// 实例化ActiveX组件对象:对word进行操作
 46   try {
 47    /*
 48     * 返回wrdCom.Documents的Dispatch
 49     * 获取Dispatch的Documents对象,可以把每个Dispatch对象看成是对Activex控件的一个操作
 50     * 这一步是获得该ActiveX控件的控制权。
 51     */
 52    wrdDocs = wrdCom.getProperty("Documents").toDispatch();
 53    // 设置打开的word应用程序是否可见
 54    wrdCom.setProperty("Visible", new Variant(false));
 55    retFlag = true;
 56   } catch (Exception e) {
 57    retFlag = false;
 58    e.printStackTrace();
 59   }
 60   return retFlag;
 61  }
 62 
 63  /**
 64   * 创建一个新的word文档
 65   * 
 66   */
 67  public void createNewDocument() {
 68   // 创建一个新的文档
 69   doc = Dispatch.call(wrdDocs, "Add").toDispatch();
 70   // 获得当前word文档文本
 71   docSelection = Dispatch.get(wrdCom, "Selection").toDispatch();
 72  }
 73 
 74  /**
 75   * 取得活动窗体对象
 76   * 
 77   */
 78  public void getActiveWindow() {
 79   // 获得活动窗体对象
 80   activeWindow = wrdCom.getProperty("ActiveWindow").toDispatch();
 81  }
 82 
 83  /**
 84   * 打开一个已存在的文档
 85   * 
 86   * @param docPath
 87   */
 88  public void openDocument(String docPath) {
 89   if (this.doc != null) {
 90    this.closeDocument();
 91   }
 92   this.doc = Dispatch.call(wrdDocs, "Open", docPath).toDispatch();
 93   this.docSelection = Dispatch.get(wrdCom, "Selection").toDispatch();
 94  }
 95 
 96  /**
 97   * 关闭当前word文档
 98   * 
 99   */
100  public void closeDocument() {
101   if (this.doc != null) {
102    Dispatch.call(this.doc, "Save");
103    Dispatch.call(this.doc, "Close", new Variant(true));
104    this.doc = null;
105   }
106  }
107   /**
108   * 文档设置图片水印
109   * 
110   * @param waterMarkPath
111   *            水印路径  */
112  public void setWaterMark(String waterMarkPath) {
113   // 取得活动窗格对象
114   Dispatch activePan = Dispatch.get(this.activeWindow, "ActivePane")
115     .toDispatch();
116   // 取得视窗对象
117   Dispatch view = Dispatch.get(activePan, "View").toDispatch();
118   // 打开页眉,值为9,页脚为10
119   Dispatch.put(view, "SeekView", new Variant(9));
120   //获取页眉和页脚
121   Dispatch headfooter = Dispatch.get(this.docSelection, "HeaderFooter")
122     .toDispatch();
123   // 获取水印图形对象
124   Dispatch shapes = Dispatch.get(headfooter, "Shapes").toDispatch();
125   // 给文档全部加上水印,设置了水印效果,内容,字体,大小,是否加粗,是否斜体,左边距,上边距。
126     //调用shapes对象的AddPicture方法将全路径为picname的图片插入当前文档
127      Dispatch picture = Dispatch.call(shapes, "AddPicture", waterMarkPath).toDispatch();
128   //选择当前word文档的水印
129   Dispatch.call(picture, "Select");
130   Dispatch.put(picture, "Left", new Variant(0));
131   Dispatch.put(picture, "Top", new Variant(150));
132   Dispatch.put(picture, "Width", new Variant(150));
133   Dispatch.put(picture, "Height", new Variant(80));
134  
135  //关闭页眉
136   Dispatch.put(view, "SeekView", new Variant(0));
137  }
138 
139  /**
140   * 关闭Word资源
141   * 
142   * 
143   */
144  public void closeWordObj() {
145   // 关闭word文件
146   wrdCom.invoke("Quit", new Variant[] {});
147   // 释放com线程。根据jacob的帮助文档,com的线程回收不由java的垃圾回收器处理
148   ComThread.Release();
149  }
150 
151  /**
152   * 得到文件名
153   * 
154   * @return .
155   */
156  public String getFileName() {
157   return fileName;
158  }
159 
160  /**
161   * 设置文件名
162   * 
163   * @param fileName .
164   */
165  public void setFileName(String fileName) {
166   this.fileName = fileName;
167  }
168 
169  /**
170   * 开始为word文档添加水印
171   * 
172   * @param wordPath
173   *            word文档的路径
174   * @param waterMarkPath
175   *            添加的水印图片路径
176   * @return 是否成功添加
177   */
178  public boolean addWaterMark(String wordPath, String waterMarkPath) {
179   try {
180    if (initWordObj()) {
181     openDocument(wordPath);
182     getActiveWindow();
183     setWaterMark(waterMarkPath);
184     closeDocument();
185     closeWordObj();
186     return true;
187 
188    } else
189     return false;
190   } catch (Exception e) {
191       e.printStackTrace();
192       closeDocument();
193       closeWordObj();
194       return false;
195   }
196  }
197  
198  public boolean insertImage(String wordPath,String imagePath)
199  {
200       try {
201            if (initWordObj()) {
202             openDocument(wordPath);
203             getActiveWindow();
204             // 用于指定位置MoveRight以及MoveDown
205             Dispatch selection = Dispatch.get(wrdCom, "Selection").toDispatch();    
206             for(int i = 0; i < 10; i++){
207                 Dispatch.call(selection, "MoveRight");
208             }
209             for(int i = 0; i < 10; i++){
210                 Dispatch.call(selection, "MoveDown");
211             }
212             Dispatch image = Dispatch.get(selection, "InlineShapes").toDispatch();
213             Dispatch dv = Dispatch.call(image, "AddPicture", imagePath).toDispatch();            
214             Dispatch.call(dv, "Select");
215             
216             //Dispatch Left = Dispatch.get(position, "Left").toDispatch();
217             selection = Dispatch.get(wrdCom, "Selection").toDispatch();
218             Dispatch shaperange   = Dispatch.get(selection, "ShapeRange").toDispatch();
219             Dispatch wf = Dispatch.get(shaperange, "WrapFormat").toDispatch();
220             Dispatch.put(wf, "Type", "6");
221             int pcnt = Integer.parseInt(Dispatch.call(selection,"information",4).toString());
222             for(int p = 1; p < pcnt; p++){
223                 Dispatch.invoke(selection, "Goto", Dispatch.Method, new Object[] {1, 2, String.valueOf(p)}, new int[1]);
224                 for(int i = 0; i < 10; i++){
225                     Dispatch.call(selection, "MoveRight");
226                 }
227                 for(int i = 0; i < 10; i++){
228                     Dispatch.call(selection, "MoveDown");
229                 }
230                 Dispatch imagef = Dispatch.get(selection, "InlineShapes").toDispatch();
231                 Dispatch dvf = Dispatch.call(imagef, "AddPicture", imagePath).toDispatch();            
232                 Dispatch.call(dvf, "Select");
233                 
234                 //Dispatch Left = Dispatch.get(position, "Left").toDispatch();
235                 selection = Dispatch.get(wrdCom, "Selection").toDispatch();
236                 Dispatch shaperangef   = Dispatch.get(selection, "ShapeRange").toDispatch();
237                 Dispatch wff = Dispatch.get(shaperangef, "WrapFormat").toDispatch();
238                 Dispatch.put(wff, "Type", "6");
239                 
240                 Dispatch.put(selection, "Start", 0); // 回到页首
241             }
242              
243             closeDocument();
244             closeWordObj();
245             return true;
246            } else
247             return false;
248           } catch (Exception e) {
249               e.printStackTrace();
250               closeDocument();
251               closeWordObj();
252               return false;
253           }
254  }
255  
256  
257  /**
258   * 测试功能
259   * 
260   */
261  public static void main(String[] argv) {
262   WordInsertPicture wordObj = WordInsertPicture.getInstance();
263 //System.out.println(wordObj.getDocPages());
264   wordObj.insertImage("e://1//Adf.docx", "e://1//watermark.png");
265   //wordObj.addWaterMark("e://1//1.doc", "e://1//watermark.png");
266  }
267 }

 

posted @ 2013-07-31 08:59  郑宇  阅读(2857)  评论(0编辑  收藏  举报