B/S 架構下,瀏覽器無法直接存取客戶端印表機進行精準套印 (如發票、報表)。解決方案:開發 ActiveX 元件 (COM),客戶端安裝後,網頁以 VBScript/JavaScript 呼叫元件方法進行列印。
// IPrintTest3 (Type Library)
interface IPrintTest3 : IDispatch
{
[id(1)] HRESULT prtCustomPage([in] long PageWidth, [in] long PageHeight); // 0.1mm 單位
[id(2)] HRESULT prtStart(); // 初始化印表機
[id(3)] HRESULT prtNewPage(); // 換頁
[id(4)] HRESULT prtEnd(); // 結束列印
[id(5)] HRESULT prtDrawLine([in] long X1, [in] long Y1, [in] long X2, [in] long Y2, [in] long LineWidth);
[id(6)] HRESULT prtSetFont([in] BSTR FontName, [in] long FontSize);
[id(7)] HRESULT prtTextRect([in] long VAlign, [in] long HAlign,
[in] long Left, [in] long Top, [in] long Right, [in] long Bottom,
[in] BSTR PrintString);
[propget, id(8)] HRESULT IsInit([out, retval] long* Val); // 初始化成功旗標
};
function TPrintTest3.InitPrintPaper: Boolean;
var
DevMode: PDEVMODE;
Device, Driver, Port: array[0..255] of Char;
hDevMode: THandle;
begin
Result := False;
if not FIsCustomPaper then Exit;
Printer.GetPrinter(Device, Driver, Port, hDevMode);
if hDevMode = 0 then Exit;
DevMode := GlobalLock(hDevMode);
try
if DevMode = nil then Exit;
with DevMode^ do
begin
dmFields := dmFields or DM_PAPERSIZE or DM_PAPERLENGTH or DM_PAPERWIDTH or DM_ORIENTATION;
dmPaperSize := DMPAPER_USER;
dmPaperWidth := FPaperWidth * 10; // 0.1mm → 0.01mm (DEVMODE 單位)
dmPaperLength := FPaperHeight * 10;
dmOrientation := IfThen(FOrientation = 0, DMORIENT_PORTRAIT, DMORIENT_LANDSCAPE);
dmCopies := 1;
end;
GlobalUnlock(hDevMode);
Printer.SetPrinter(Device, Driver, Port, hDevMode);
Result := True;
except
GlobalUnlock(hDevMode);
end;
end;
function TPrintTest3.MMToPrinterPixels(const Pt: TPoint): TPoint;
var
DPIX, DPIY: Integer;
begin
if not FCachedDPI then
begin
DPIX := GetDeviceCaps(Printer.Handle, LOGPIXELSX);
DPIY := GetDeviceCaps(Printer.Handle, LOGPIXELSY);
FDPIX := DPIX; FDPIY := DPIY; FCachedDPI := True;
end;
// 1 inch = 25.4 mm = 254 * 0.1mm
Result.X := MulDiv(Pt.X, FDPIX, 2540);
Result.Y := MulDiv(Pt.Y, FDPIY, 2540);
end;
<script language="VBScript">
<!--
Sub TestPrint
Dim Obj
Set Obj = CreateObject("PrintTest3.PrintTest3")
Obj.prtCustomPage 1000, 1000 ' 100mm x 100mm
Obj.prtStart
If Obj.IsInit Then
Obj.prtDrawLine 0, 0, 1000, 1000, 1
Obj.prtSetFont "新細明體", 16
Obj.prtTextRect 2, 2, 0, 0, 1000, 500, "Web 列印測試"
Obj.prtEnd
End If
Set Obj = Nothing
End Sub
TestPrint()
-->
</script>
.dll、.tlb,執行 regsvr32 PrintTest3.dll。ActiveX 僅限 IE/Windows。現代 Web 列印建議:
window.print() + CSS @media print 排版。print.js)。