JAVA的Web打印方式(PageOffice、POI、jacob,html打印等)


之前因為需要,去學習了幾種WEB報表的打印方式,發現用Java直接去操作Word、Excel還是不那么方便,下面就簡單介紹幾種;

1、用瀏覽器自帶的打印功能直接打印;

  這種方式是最直接的,方便的,不需要加什么插件jar包,只要前台在一個 div 中模仿着報表的格式去設置界面布局,然后把數據動態的填充進去,再調用JavaScript打印函數,就可以實現界面的局部打印功能。(如果不想讓報表div在界面中顯示出來可以隱藏之)PS:不過直接在前台界面打印還是會遇到意想不到的情況,不同瀏覽器的問題,反正我就遇到不同瀏覽器打印出來的報表排版不一的情況,用的 時候需要注意。

  eg:

  div布局

<div id="printdiv" style="display:none;">
  <table id="tableid" class="main" cellspacing="0" cellpadding="0" border="1"
      bordercolor="#000000" align="center" width="800px;">
       /******    your     code      ******/
   </table>
</div>

JavaScript部分:(自己根據需要選擇觸發響應的JS函數)

function windowprint() {
    
    var f = document.getElementById("printdiv");
    f.style.display = "";
    window.print();
    f.style.display = "none";
}

function myPrint(obj){

    var newWindow=window.open("打印窗口","_blank");
    var docStr = obj.innerHTML;
       newWindow.document.write(docStr);
    newWindow.document.close();
    newWindow.print();
    newWindow.close();
}

2、使用第三方插件完成報表打印編輯(這里介紹PageOffice 和 Jacob)

  先說PageOffice,這是國產貨,其強大之處在於其對Word的處理和它的在線編輯能力,最大的不足就是要收費(不過也不知道怎么收,下載的包里有自帶的試用碼,也不管先用着玩玩)

  准備:去官網下載java版本的包(http://www.zhuozhengsoft.com/download.html),解壓后需要把PageOffice.cab和pageoffice.jar兩個包放到WEB-INF/lib中去還要在你的web.xml中加入以下部分:

<!-- PageOffice Begin -->
  <servlet>
    <servlet-name>poserver</servlet-name> 
    <servlet-class>com.zhuozhengsoft.pageoffice.poserver.Server</servlet-class> 
  </servlet>
  <servlet-mapping> 
    <servlet-name>poserver</servlet-name> 
    <url-pattern>/poserver.do</url-pattern> 
  </servlet-mapping> 
  <servlet-mapping> 
    <servlet-name>poserver</servlet-name> 
    <url-pattern>/pageoffice.cab</url-pattern>
  </servlet-mapping>
  <servlet-mapping> 
    <servlet-name>poserver</servlet-name> 
    <url-pattern>/popdf.cab</url-pattern>
  </servlet-mapping>
  <servlet-mapping> 
    <servlet-name>poserver</servlet-name> 
    <url-pattern>/sealsetup.exe</url-pattern>
  </servlet-mapping>
  <servlet>
    <servlet-name>adminseal</servlet-name> 
    <servlet-class>com.zhuozhengsoft.pageoffice.poserver.AdminSeal</servlet-class> 
  </servlet>
  <servlet-mapping> 
    <servlet-name>adminseal</servlet-name> 
    <url-pattern>/adminseal.do</url-pattern> 
  </servlet-mapping>
  <servlet-mapping> 
    <servlet-name>adminseal</servlet-name> 
    <url-pattern>/loginseal.do</url-pattern>
  </servlet-mapping>
  <servlet-mapping> 
    <servlet-name>adminseal</servlet-name> 
    <url-pattern>/sealimage.do</url-pattern>
  </servlet-mapping>
  <mime-mapping>  
      <extension>mht</extension>  
      <mime-type>message/rfc822</mime-type>  
  </mime-mapping>
  <context-param>
      <param-name>adminseal-password</param-name>
      <param-value>123456</param-value>
  </context-param>
  
  <!--<context-param>
      <param-name>posealdb-driver</param-name>
      <param-value>com.mysql.jdbc.Driver</param-value>
  </context-param>
  <context-param>
      <param-name>posealdb-url</param-name>
      <param-value>jdbc:mysql://localhost:3306/sample</param-value>
  </context-param>
  <context-param>
      <param-name>posealdb-username</param-name>
      <param-value>root</param-value>
  </context-param>
  <context-param>
      <param-name>posealdb-password</param-name>
      <param-value>admin</param-value>
  </context-param>-->
  <!-- PageOffice End -->

然后就可以直接用了

  eg:直接貼一個Struts2下使用的Demo好了

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.*;
import com.opensymphony.xwork2.ActionSupport;
import com.zhuozhengsoft.pageoffice.*;

public class WordDemo extends ActionSupport implements ServletRequestAware, ServletResponseAware{ 

    private static final long serialVersionUID = -758686623642845302L;
    private HttpServletRequest request;
    private HttpServletResponse response; 
    private String message = "";
    
    public void setServletRequest(HttpServletRequest request) { 
        this.request = request; 
    }
    public void setServletResponse(HttpServletResponse response) { 
        this.response = response; 
    }
    
    public String getMessage(){
        return message;
    }

    public String openword() throws Exception {
        PageOfficeCtrl poCtrl1 = new PageOfficeCtrl(ServletActionContext.getRequest());
        poCtrl1.setServerPage("poserver.do"); //此行必須
        // 加載控件,可以顯示在在線編輯欄中
        poCtrl1.addCustomToolButton("保存", "SaveDocument()", 1);
        poCtrl1.addCustomToolButton("-", "", 0);
        poCtrl1.addCustomToolButton("打印", "ShowPrintDlg()", 6);
        poCtrl1.addCustomToolButton("-", "", 0);
        poCtrl1.addCustomToolButton("全屏切換", "SetFullScreen()", 4);
        poCtrl1.addCustomToolButton("-", "", 0);
        poCtrl1.addCustomToolButton("加蓋印章", "AddSeal()", 5);
        poCtrl1.addCustomToolButton("手寫簽批", "AddHandSign()", 5);
        poCtrl1.addCustomToolButton("驗證印章", "VerifySeal()", 5);
        
        poCtrl1.setSaveFilePage("saveword.action");
        
     // 打開WebRoot/doc/test.doc模版 
poCtrl1.webOpen(
"doc/test.doc", OpenModeType.docNormalEdit, "張三"); poCtrl1.setTagId("PageOfficeCtrl1"); //此行必須 return "openword_"+SUCCESS; } public String saveword() throws Exception { FileSaver fs = new FileSaver(request, response); request.setAttribute("FileSaver", fs); String fileName = "\\maker" + fs.getFileExtName(); fs.saveToFile(request.getSession().getServletContext().getRealPath("doc/")+ fileName);//fs.getFileName() fs.showPage(150, 150); message = "保存文件至服務器成功!"; return "saveword_"+SUCCESS; } }

還可以在模版中設置書簽指定動態替換,不過需要注意一點的是在返回的JSP界面中<body>中需要加入

<po:PageOfficeCtrl id="PageOfficeCtrl1" />

  關於具體的,可以參考他的文檔,是中文的文檔,而且官網還可以下載很多Demo參考,沒什么可以說的了,PS:不過就是感覺它在網頁中直接打開word速度有點慢,不過這可能是微軟問題。。

  B:jacob

  簡單的看了一下,又是要加jar包,還要把它那dll文件放到你的系統路徑下,感覺好煩的樣子,具體怎么做網上也能找到,不再贅述。

  eg:(貼一個小例子)

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


public class JacobTest {

    public static void main(String[] args) {
        //啟動word,生成一個ActivexComponent對象
        ActiveXComponent app = new ActiveXComponent("Word.Application");
        //要轉換的word文件
        String inFile = "D:\\demo.doc";
        //要報存的目標文件
        String tpFile ="D:\\demo1.doc";
        boolean flag = false;
        Dispatch xlo = app.getObject();
        String oldText="1234";
        String newText="test";
        boolean visible=false;
        String bookMarkKey1="LB_KJGG";
        String bookMarkKey2="PO_Sex";
        
        try {
          //設置word不可見
          app.setProperty("Visible", new Variant(visible));
          //log.info("設置word不可見成功!");
          System.out.println("設置word不可見成功!");
          Dispatch docs = app.getProperty("Documents").toDispatch();
          Dispatch doc = Dispatch.invoke(docs, "Open", Dispatch.Method, new Object[]{inFile, new Variant(false), new Variant(true)}, new int[1]).toDispatch(); //打開word文件
          //在word2003的vba文檔中application有UserName屬性。
          String userName=app.getPropertyAsString("UserName");
          System.out.println("用戶名:"+userName);
          Dispatch selection=app.getProperty("Selection").toDispatch();
          //得到一個組件
          System.out.println("Selection");
          Dispatch find = app.call(selection, "Find").toDispatch();

           //查找什么文本
           Dispatch.put(find, "Text", oldText);
           //替換文本
           Dispatch.call(find,"ClearFormatting");
           Dispatch.put(find, "Text", oldText);
           Dispatch.call(find, "Execute");
           Dispatch.put(selection, "Text", newText);
           // Dispatch.call(app, "SaveAs", inFile);
           System.out.println("replace");
           
           //把指定的值設置到指定的標簽中去
           Dispatch activeDocument=app.getProperty("ActiveDocument").toDispatch();
           System.out.println("activedocument");
           Dispatch bookMarks = app.call(activeDocument, "Bookmarks").toDispatch();
           System.out.println("bookmarks");
           boolean bookMarkExist1=Dispatch.call(bookMarks,"Exists",bookMarkKey1).toBoolean();
           boolean bookMarkExist2=Dispatch.call(bookMarks,"Exists",bookMarkKey2).toBoolean();
           if(bookMarkExist1==true){
               System.out.println("exists bookmark!");
               Dispatch rangeItem = Dispatch.call(bookMarks, "Item",bookMarkKey1).toDispatch();
               System.out.println("range item!");
               Dispatch range = Dispatch.call(rangeItem, "Range").toDispatch();
               System.out.println("range !");
               //取標簽的值
               String bookMarkValue=Dispatch.get(range,"Text").toString();
               
               bookMarkValue="hello";
                if(bookMarkValue!=null){
                  Dispatch.put(range, "Text", new Variant(bookMarkValue));
                }
           }else{
             System.out.println("not exists bookmark!");
           }
          //保存文件
          Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[] {tpFile, new Variant(0)}                      , new int[1]);
          //作為word格式保存到目標文件
          Variant f = new Variant(false);
          Dispatch.call(doc, "Close", f);
          flag = true;
        }
        catch (Exception e) {
          e.printStackTrace();
        }
        finally {
          app.invoke("Quit", new Variant[] {});
        }
    }
    
}

3、還有一個技術,POI,其實第一個就學的這個。對Excel的處理還行,對word的處理,讀取還過的去,但是寫入,尤其是寫入圖片,不知道能么辦,而且用起來好麻煩。(真是想不通都搞了10來年的技術了,還這樣。。)

eg1:(向word中插入一段文本)

import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.hwpf.model.io.HWPFFileSystem;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

/*
 * 可以向word中插入文本
 * */
public class TestWrite4 {

    public static void main(String[] args) throws Exception {
        
        HWPFFileSystem files = new HWPFFileSystem();

        try
        {
        String str =
        "This is our first doc file Jojiiiiiiiiiiii….We Got IT..But not sure !!";
        str += "rn這是我的第一個doc例子!";
        byte b[] = str.getBytes();
        ByteArrayInputStream bais = new ByteArrayInputStream(b);

        POIFSFileSystem fs = new POIFSFileSystem();
        DirectoryEntry directory = fs.getRoot();

        DocumentEntry de = directory.createDocument("WordDocument", bais);

        FileOutputStream ostream = new FileOutputStream("d:\\testCreate.doc");

        fs.writeFilesystem(ostream);
        bais.close();
        ostream.close();

        }
        catch (IOException e)
        {

        e.printStackTrace();
        }
    }

}

還有一些具體的功能操作,以及對於Excel的操作,推薦一個網站介紹的比較好。http://word.apachepoi.com/

還在網上看到可以通過 Applet方式完成報表的打印,不過沒去研究過。。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM