博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jacob 给word加印的功能
阅读量:4522 次
发布时间:2019-06-08

本文共 9659 字,大约阅读时间需要 32 分钟。

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

关键的心得如下:

使用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上并没有给出很直观的例子,甚至还找到了此功能无法实现的文章。直到找到了一篇名为“”的帖子,并注意到里面使用的

  //定位到第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 waterMarkPath111   *            水印路径  */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,页脚为10119   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 wordPath173   *            word文档的路径174   * @param waterMarkPath175   *            添加的水印图片路径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    } else189     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以及MoveDown205             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            } else247             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 }

 

转载于:https://www.cnblogs.com/rain64531264/p/jacob_word.html

你可能感兴趣的文章
Boost库编译安装
查看>>
Python matplot画散列图
查看>>
C#/.NET整数的三种强制类型转换(int)、Convert.ToInt32()、int.Parse()的区别
查看>>
算法复习——数位dp(不要62HUD2089)
查看>>
PhpSpreadsheet如何读取excel文件
查看>>
如何选购一款好的人事档案管理系统
查看>>
Spark2.1.0——运行环境准备
查看>>
[转载]C#异步调用四大方法详解
查看>>
在windows下添加php的Imagick扩展
查看>>
python3 爬取百合网的女人们和男人们
查看>>
kubernetes源码阅读笔记——Kubelet(之三)
查看>>
如何利用jQuery post传递含特殊字符的数据
查看>>
中国剩余定理
查看>>
Codeforces 543.B Destroying Roads
查看>>
noip模拟赛 寻宝之后
查看>>
洛谷P1461 海明码 Hamming Codes
查看>>
ZOJ2833*(并查集)
查看>>
外连接简要总结
查看>>
第一次作业-准备篇
查看>>
【C++】继承时构造函数和析构函数
查看>>