首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

J2EE 系統中集成 Cell ActiveX 插件實現複雜報表打印

     編輯:Java 程式設計入門

業務背景與技術難點

J2EE 系統前端採用 Java Applet 豐富交互,但 Java 打印 API (java.awt.print) 功能弱、佈局困難、分頁邏輯需手寫。引入 **華表 Cell 插件 (ActiveX)** 專業解決:

  • Excel 級表格編輯、公式、圖表、分頁預覽
  • 直接輸出打印機、導出 PDF/Excel
  • Applet 負責業務數據組裝,Cell 負責排版渲染打印 —— **職責分離**

核心技術橋樑:Applet ↔ JavaScript ↔ ActiveX

Sun 提供 netscape.javascript.JSObject (在 jaws.jar / plugin.jar) 實現三方互通:

1. Applet 調用 JavaScript / ActiveX

import netscape.javascript.JSObject;

public class MyApplet extends Applet {
    public void init() {
        JSObject win = JSObject.getWindow(this);        // 獲取 window
        JSObject doc = (JSObject) win.getMember("document"); // 獲取 document
        win.call("jsFunctionName", null);               // 調用 JS 函數
        // 或直接操作 ActiveX (通過 document.all)
        JSObject all = (JSObject) doc.getMember("all");
        JSObject cell = (JSObject) all.call("item", new Object[]{"DCellWeb1"}); // ID 定位
        cell.call("SetCellString", new Object[]{col, row, page, "數據"});      // 調用 Cell 方法
    }
}

2. JavaScript 調用 Applet 公共方法


// HTML 
// JS 中直接調用
myApplet.publicMethodInApplet();

需 JRE 1.4+ / Java Plugin,Applet 方法聲明 public。

Cell 插件嵌入與隱藏

<object id="DCellWeb1" classid="clsid:...Cell插件CLSID..."
        width="0" height="0"> <!-- 隱藏,僅作打印引擎 -->
</object>

系統架構圖解

部署架構:三層 + 客戶端 Applet+Cell

運行時序:Applet→Servlet→EJB,打印時 Applet→Cell

  • **部署層**:Applet JAR + Cell CAB/OCX 部署於 Web Server,客戶端瀏覽器自動下載安裝
  • **運行層**:Applet (表示層) ↔ Servlet (控制器) ↔ EJB (業務/持久層)
  • **打印流程**:用戶點打印 → Applet 組裝數據/格式 → 逐單元格寫入 Cell → 調用 Cell PrintPreview()/Print()

Applet 端封裝通用調用接口


public class ReportApplet extends JApplet {
    private JSObject win, cell;

    // 供業務邏輯調用:向 Cell 寫入單元格
    public void setCellData(int col, int row, int page, String value) {
        callCell("SetCellString", new Object[]{col, row, page, value});
    }

    // 供業務邏輯調用:觸發打印預覽
    public void printPreview() {
        callCell("PrintPreview", null);
    }

    // 供業務邏輯調用:直接打印
    public void print() {
        callCell("Print", null);
    }

    private Object callCell(String method, Object[] params) {
        if (cell == null) initCell();
        try { return cell.call(method, params); }
        catch (Exception ex) { ex.printStackTrace(); return null; }
    }

    private void initCell() {
        try {
            win = JSObject.getWindow(this);
            JSObject doc = (JSObject) win.getMember("document");
            JSObject all = (JSObject) doc.getMember("all");
            cell = (JSObject) all.call("item", new Object[]{"DCellWeb1"});
        } catch (Exception e) { e.printStackTrace(); }
    }

    // 兼容 JS 調用 Applet
    public Object callFromJS(String method, Object[] params) {
        try {
            java.lang.reflect.Method m = getClass().getMethod(method, Object[].class);
            return m.invoke(this, (Object) params);
        } catch (Exception ex) { ex.printStackTrace(); return null; }
    }
}

業務邏輯調用示例


// 在 Applet 某事件中生成報表並打印
public void generateAndPrintOrderReport(Order order) {
    // 1. 設置頁眉
    setCellData(1, 1, 0, "銷售訂單");
    setCellData(1, 2, 0, "訂單號:" + order.getId());
    setCellData(1, 3, 0, "客戶:" + order.getCustomerName());
    setCellData(1, 4, 0, "日期:" + order.getDate());

    // 2. 設置表頭
    String[] headers = {"行號", "產品", "數量", "單價", "金額"};
    for (int i = 0; i < headers.length; i++) setCellData(i + 1, 6, 0, headers[i]);

    // 3. 填充明細行
    int row = 7;
    for (OrderItem item : order.getItems()) {
        setCellData(1, row, 0, String.valueOf(row - 6));
        setCellData(2, row, 0, item.getProductName());
        setCellData(3, row, 0, String.valueOf(item.getQty()));
        setCellData(4, row, 0, String.valueOf(item.getPrice()));
        setCellData(5, row, 0, String.valueOf(item.getAmount()));
        row++;
    }

    // 4. 設置頁腳合計
    setCellData(1, row, 0, "合計:");
    setCellData(5, row, 0, String.valueOf(order.getTotal()));

    // 5. 打印預覽 (用戶確認後再打印)
    printPreview();
}

關鍵優勢總結

維度純 Java 打印Cell 插件方案
佈局靈活性低 (手繪坐標/表格)高 (Excel 式所見即所得)
分頁控制手寫分頁邏輯自動分頁、分頁預覽
開發工作量大 (幾百行打印代碼)小 (數據填充幾十行)
導出格式需第三方庫原生導出 PDF/Excel/HTML
客戶端依賴僅 JRE需 ActiveX (僅 IE/Windows)

遺留問題與現代化替代方向

  • 平台鎖定:ActiveX 僅限 Windows IE,現代瀏覽器 (Edge/Chrome/Firefox) 不支持。
  • 替代方案:
    1. 服務端渲染 PDF:iText / Apache PDFBox / Flying Saucer (HTML/CSS 轉 PDF) → 瀏覽器直接預覽/打印
    2. 前端 JS 表格庫:Handsontable / x-spreadsheet / Luckysheet + window.print() CSS @media print 控制
    3. WebAssembly 移植:將 Cell 核心邏輯編譯為 WASM (若有源碼授權)

對於存量 IE 專用內網系統,Cell 方案仍具備不可替代的成熟度與低成本;新建系統強烈建議採用 **服務端 PDF + 瀏覽器原生打印** 架構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved