J2EE 系統前端採用 Java Applet 豐富交互,但 Java 打印 API (java.awt.print) 功能弱、佈局困難、分頁邏輯需手寫。引入 **華表 Cell 插件 (ActiveX)** 專業解決:
Sun 提供 netscape.javascript.JSObject (在 jaws.jar / plugin.jar) 實現三方互通:
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 方法
}
}
// HTML
需 JRE 1.4+ / Java Plugin,Applet 方法聲明 public。
<object id="DCellWeb1" classid="clsid:...Cell插件CLSID..."
width="0" height="0"> <!-- 隱藏,僅作打印引擎 -->
</object>


PrintPreview()/Print()
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) |
window.print() CSS @media print 控制對於存量 IE 專用內網系統,Cell 方案仍具備不可替代的成熟度與低成本;新建系統強烈建議採用 **服務端 PDF + 瀏覽器原生打印** 架構。