打印机通过TCanvas,把表格信息输出到图片或者打印机种,表格信息的xml代码如下:
<table><tr  rowtype="title" height="25"><td  width="50">序号</td><td  width="60">产品编号</td><td  width="100">产品名称</td><td  width="80">规格</td><td  width="60">数量</td><td  width="50">单位</td><td  width="50">折扣</td><td  width="60">价格</td><td  width="50">合计</td></tr><tr  rowtype="mx" loop="6" height="25"><td  width="50" binding="rowitemno">rowitemno</td><td  width="60" binding="prono">prono</td><td  width="100" binding="proname">proname</td><td  width="80" binding="spec">spec</td><td  width="60" binding="qty">qty</td><td  width="50" binding="dw">dw</td><td  width="50" binding="zhekou">zhekou</td><td  width="60" binding="price">price</td><td  width="50" binding="salesum">salesum</td></tr><tr  rowtype="title" height="20"><td  width="50">合计</td><td  width="60"></td><td  width="100"></td><td  width="80"></td><td  width="60"></td><td  width="50"></td><td  width="50"></td><td  width="60"></td><td  width="50" binding="salesumsum"></td></tr></table>
上面代码是xml代码,通过txmldocument读取行和列,按行按单元格把线条和文本输出到打印机中,在图片中输出正确,效果如下但输出到打印机时,其他都正常,就表格第一行第一个单元格向左出现了1毫米的误差,我郁闷!!(不知道是不是打印机的问题)以下是代码:
 dbug:=1;
  act:='print';
  
  //http://localhost:8080/print?pid=20110705000002&djid=20121123000004&djtype=xsdingdan&client=delphi&act=loadview
  pid:=Get_PID();
  djid:=Get_DJID();
  djtype:=Get_DJTYPE();
  client:='delphi';
  Param:=TStringList.Create;
  RStream:=TStringStream.Create('');
  Param.Add('act=loadview');
  Param.Add('pid='+pid);
  Param.Add('djid='+djid);
  Param.Add('djtype='+djtype);
  Param.Add('client='+client);
  url:=rootpath+'print';
  self.idhttp.Post('http://localhost:8080/print',Param,RStream);
  xmlstring:='<?xml version="1.0" encoding="gb2312"?>';
  xmlstring:=xmlstring+RStream.DataString;
  pxml:=xmlstring;  mx:=TXMLDocument.Create(self);
  mx.XML.Add(xmlstring);
  mx.Active:=true;
  printname:=mx.DocumentElement.ChildNodes['printname'].Text;
  printwidth:=mx.DocumentElement.ChildNodes['printwidth'].Text;
  printheight:=mx.DocumentElement.ChildNodes['printheight'].Text;
  Printer.Title:='销售订单打印';
  SetPaperWidth(round(strtofloat(printwidth)));    //mm
  SetPaperHeight(round(strtofloat(printheight)));
  MyCanvas:=Printer.Canvas;
  Printer.BeginDoc;
  MyCanvas.Brush.Color :=clWhite;
  MyCanvas.FillRect(MyCanvas.ClipRect);  //清除残留影像
  MyCanvas.Brush.Color:=clBlue;
  MyCanvas.Brush.Style := bsclear;
  MyCanvas.Pen.Color:=clBlack;
  MyCanvas.Font.Color := clBlack;
  rowcount:=mx.DocumentElement.ChildNodes['mxbody'].ChildNodes.Count;
  pagecount:=1;
  pagesize:=0;
  tableleft:=0;
  tabletop:=0;
  tabrowcount:=0;
  tabmaxheight:=0;
  if mx.DocumentElement.ChildNodes['printtable'].ChildNodes.Count<>0 then
  begin
        pagesize:= StrToInt(mx.DocumentElement.ChildNodes['printtable'].ChildNodes['mxloop'].Text);
        if (rowcount mod  pagesize)=0 then
         pagecount:=Trunc(rowcount/pagesize)
        else
        pagecount:=Trunc(rowcount/pagesize)+1;
        tableleft:=StrToFloat(mx.DocumentElement.ChildNodes['printtable'].ChildNodes['mxx'].Text);
        tabletop:=StrToFloat(mx.DocumentElement.ChildNodes['printtable'].ChildNodes['mxy'].Text);
        tabrowcount:=mx.DocumentElement.ChildNodes['printtable'].ChildNodes['table'].ChildNodes.Count;
 end ;  tableleftold:=tableleft;
  i:=0;
  currentpage:=0;
  at:=0;
  pagecount:=1;
  
  while currentpage<pagecount do
  begin
      while i<tabrowcount    do
  begin    trnode:=mx.DocumentElement.ChildNodes['printtable'].ChildNodes['table'].ChildNodes[i];
    rowheight:=Real(trnode.Attributes['height']);
    rowtype:= trnode.Attributes['rowtype'];
    k:=0;
    cellcount:=trnode.ChildNodes.Count;     if  trnode.HasAttribute('loop')   then
       begin
          //-----------------------------------------------是明细部分----------------------------------------
             mxnum:= Integer(trnode.Attributes['loop']) ;
             mxrowheight:=Real(trnode.Attributes['height']);             while (k<mxnum) and   (((currentpage*mxnum)+k)<rowcount) do
             begin
        j:=0;
       while j<cellcount    do
       begin
        tdnode:=trnode.ChildNodes[j];
        cellwidth:=Real(tdnode.Attributes['width']);
        txt:=tdnode.Text;
        if  tdnode.HasAttribute('binding')   then
            binding:=tdnode.Attributes['binding']
         else
             binding:='';
        if i=0  then    //则画最顶端线
        begin
          _line(tableleft,tabletop,tableleft+cellwidth,tabletop,2);
        end ;        _line(tableleft,tabletop,tableleft,tabletop+rowheight,2); //画向下线
        if  (tabletop+rowheight)>tabmaxheight then
         tabmaxheight:= tabletop+rowheight;
        _line(tableleft,tabletop+rowheight,tableleft+cellwidth,tabletop+rowheight,2);//
        if j+1=cellcount   then
        begin
          _line(tableleft+cellwidth,tabletop,tableleft+cellwidth,tabletop+rowheight,2); //画向下线
        end;        if (rowtype='mx') and (binding<>'')  then
        begin
             if binding='rowitemno' then
              txt:=inttostr(k+1)
             else
              txt:= mx.DocumentElement.ChildNodes['mxbody'].ChildNodes[k+(currentpage*pagesize)].ChildNodes[binding].Text;             _outTxt(tableleft,tabletop,txt,12,'宋体',cellwidth,rowheight,100);        end
        else
        begin
               if txt<>'' then
                _outTxt(tableleft,tabletop,txt,12,'宋体',cellwidth,rowheight,100);
        end ;
        j:=j+1;
        tableleft:=tableleft+cellwidth;         end ; //end cellloop
         tableleft:=tableleftold;
         tabletop:=tabletop+rowheight;
         k:=k+1 ;
     end;
             at:=mxnum-k;
          //---------------------------------------------------结束明细------------------------------------------------
       end
     else
     begin
          // ----------------------------------------------- 标题部分或者汇总----------------------------------------
        j:=0;
       while j<cellcount    do
       begin
        tdnode:=trnode.ChildNodes[j];
        cellwidth:=Real(tdnode.Attributes['width']);
        txt:=tdnode.Text;
        if  tdnode.HasAttribute('binding')   then
            binding:=tdnode.Attributes['binding']
         else
             binding:='';         if binding<>'' then
          txt:=trim(mx.DocumentElement.ChildNodes['titles'].ChildNodes[binding].Text);
        if i=0  then    //则画最顶端线
          _line(tableleft,tabletop,tableleft+cellwidth,tabletop,2);
        _line(tableleft,tabletop,tableleft,tabletop+rowheight,2); //画向下线
        _line(tableleft,tabletop+rowheight,tableleft+cellwidth,tabletop+rowheight,2);//底线        if  (tabletop+rowheight)>tabmaxheight then
         tabmaxheight:= tabletop+rowheight;         if j+1=cellcount   then
         begin
          _line(tableleft+cellwidth,tabletop,tableleft+cellwidth,tabletop+rowheight,2); //画向下线
         end;
         if txt<>'' then
             _outTxt(tableleft,tabletop,txt,12,'宋体',cellwidth,rowheight,100);        j:=j+1;
        tableleft:=tableleft+cellwidth;         end ; //end cellloop
         tableleft:=tableleftold;
         tabletop:=tabletop+rowheight;
          //------------------------------------------------结束标题或者汇总---------------------------------------------------
      end ;
      i:=i+1;   end;//end table    n:=0;
     
    while n<mx.DocumentElement.ChildNodes['printlabel'].ChildNodes.Count  do
    begin
           node:=mx.DocumentElement.ChildNodes['printlabel'].ChildNodes[n];
           txt:=trim(node.ChildNodes['txt'].Text);
           bindingdata:=trim(node.ChildNodes['bindingdata'].Text);
           fontsize:=trim(node.ChildNodes['fontsize'].Text);
           x:=trim(node.ChildNodes['x'].Text);
           y:=trim(node.ChildNodes['y'].Text);
           fontweight:=trim(node.ChildNodes['fontweight'].Text);           yy:=StrToFloat(y);
           if (at<>0) and (yy>tabmaxheight) then
            yy:=yy-(at*mxrowheight);           if bindingdata<>'' then
           txt:=trim(mx.DocumentElement.ChildNodes['titles'].ChildNodes[bindingdata].Text);           txt:=StringReplace(txt,'$currentpage',IntToStr(currentpage+1),[rfReplaceAll]);
           txt:=StringReplace(txt,'$pagecount',FloatToStr(pagecount),[rfReplaceAll]);
           txt:=StringReplace(txt,'$cpname',mx.DocumentElement.ChildNodes['cpname'].Text,[rfReplaceAll]);
           txt:=StringReplace(txt,'$cptel',mx.DocumentElement.ChildNodes['cptel'].Text,[rfReplaceAll]);
           txt:=StringReplace(txt,'$cpaddr',mx.DocumentElement.ChildNodes['cpaddr'].Text,[rfReplaceAll]);
           txt:=StringReplace(txt,'$weburl',mx.DocumentElement.ChildNodes['weburl'].Text,[rfReplaceAll]);
           _outTxt(StrToFloat(x),yy,txt,StrToFloat(fontsize),'宋体',0,0,StrToFloat(fontweight));
           n:=n+1;    end ;
   currentpage:=currentpage+1;
   if currentpage<pagecount then
   begin
    Printer.NewPage()
    end;  end ;
Printer.EndDoc;