这里的打印应该要使用printer.canvas才能实现了。
首先你要确定一个页面上可以打印多少条记录,并且记录的高度和记录间的间距是多少,算好之后把值传递给printer.canvas,控制在新的位置上直接打印。
如果用quickrep也应该可以。用一个titleband,上面放好N条记录所需要的控件(dbedit),datasource是一个用clientdataset做的临时表。那打印的时候首先算出有多少记录是空得(以前打印过),然后新记录就直接放在空记录的后面输出。这样也应该可以,试一试已经被打印过的记录必须用标记在记录中标识

解决方案 »

  1.   

    谢谢各位的参与!
    TO: cobi(我是小新) :
    具体的位置怎样确定?能给我点代码参考吗?我对那种方式不熟。谢谢!
      

  2.   

    这是一个的有关于printext的例子,不过你还要确定你所要打印的位置。
    function TRepBoKuanTongZhi.AvgCharWidth: Word;   //取得字符的平均宽度
    var
      Metrics: TTextMetric;
    begin
      GetTextMetrics(Printer.Canvas.Handle, Metrics);
      Result := Metrics.tmAveCharWidth;
    end;function TRepBoKuanTongZhi.CharHeight: Word;       //取得字符的高度
    var
      Metrics: TTextMetric;
    begin
      GetTextMetrics(Printer.Canvas.Handle, Metrics);
      Result := Metrics.tmHeight;
    end;function TRepBoKuanTongZhi.GetOffSetX: Integer;     //取得纸张的横向偏移量-单位:点
    begin
      result:=getdevicecaps(printer.Handle,physicaloffsetx);
    end;function TRepBoKuanTongZhi.GetOffSetY: Integer;     //取得纸张的纵向偏移量-单位:点
    begin
      Result := GetDeviceCaps(Printer.Handle, PhysicalOffSetY);
    end;function TRepBoKuanTongZhi.GetPhicalPaper: TPoint;  //取得纸张的物理尺寸---单位:点
    var
      pagesize:tpoint;
    begin
      //PageSize.X; 纸张物理宽度-单位:点
      //PageSize.Y; 纸张物理高度-单位:点
      escape(printer.Handle,GETPHYSPAGESIZE,0,nil,@pagesize);
      result:=pagesize;
    end;function TRepBoKuanTongZhi.HPointsPerInch: Integer;  //取得水平方向每英寸打印机的点数
    begin
      Result := GetDeviceCaps(Printer.Handle, LOGPIXELSX);
    end;function TRepBoKuanTongZhi.HVLogincRatio: Extended;  //纸张水平对垂直方向的纵横比例
    var
      ap:tpoint;
    begin
      ap:=paperlogicsize;
      result:=ap.y/ap.x;
    end;function TRepBoKuanTongZhi.InchToMm(Length: Extended): Extended; //英寸单位转换为毫米单位
    begin
      Result := Length*25.4;
    end;function TRepBoKuanTongZhi.MmToInch(Length: Extended): Extended;  //毫米单位转换为英寸单位
    begin
      Result := Length/25.4;
    end;function TRepBoKuanTongZhi.PaperLogicSize: TPoint;    //.取得纸张的逻辑宽度--可打印区域,取得纸张的逻辑尺寸
    var
      apoint:tpoint;
    begin
      apoint.x:=printer.PageWidth;
      apoint.y:=printer.PageHeight;
      result:=apoint;
    end;procedure TRepBoKuanTongZhi.PrintText(X, Y: Extended; Txt,
      ConfigFileName: string; FontSize: Integer);  //在 (Xmm, Ymm)处按指定配置文件信息和字体输出字符串
    var
      orx,ory:extended;
      px,py:integer;
      ap:tpoint;
      fn:tstrings;  offsetx,offsety:integer;
    begin
      try
        fn:=tstringlist.Create;
        filename:=ExtractFilePath(Application.ExeName)+'config.txt';
        if fileexists(filename) then
        begin
          fn.LoadFromFile(filename);
          //横向偏移量
          OffSetX:= StrToInt(Fn.Values['X']);
          //纵向偏移量
          OffSetY := StrToInt(Fn.Values['Y']);
        end
        else
        begin
          //如果没有配置文件,则生成
          fn.Values['x']:='0';
          fn.values['y']:='0';
          fn.SaveTofile(filename);
        end;
      finally
        fn.Free;
      end;
      x:=x+offsetx;
      y:=y+offsety;
      Px:=Round(Round(X * HPointsPerInch * 10000/25.4)/10000);
      Py:=Round(Round(Y * VPointsPerInch * 10000/25.4)/10000);
      py:=py-getoffsety; //因为是绝对坐标, 因此, 不用换算成相对于Y轴坐标
      px:=px+2*avgcharwidth;
      if printlog=0 then
      begin
        Printer.Canvas.Font.Name:= '宋体';
        Printer.Canvas.Font.Size:=10;
      end
      else if printlog=1 then
      begin
        Printer.Canvas.Font.Name:= '楷体_GB2312';      //
        printer.Canvas.Font.Size:=16;
      end;  Printer.Canvas.TextOut(Px, Py, Txt);
    end;procedure TRepBoKuanTongZhi.SetPaperHeight(Value: integer);
    var
      device: array[0..255] of char;
      driver: array[0..255] of char;
      port:   array[0..255] of char;
      hdmode: thandle;
      PDMode: PDEVMODE;
    begin
      //自定义纸张最小高度127mm
      if Value <  127 then Value:=127;
      //自定义纸张最大高度432mm
      if value>432 then value:=432;
      printer.PrinterIndex:=printer.PrinterIndex;
      printer.GetPrinter(device,driver,port,hdmode);
      if hDMode <> 0 then
      begin
        pDMode := GlobalLock(hDMode);
        if pDMode <>  nil then
        begin
          pDMode^.dmFields := pDMode^.dmFields or DM_PAPERSIZE or DM_PAPERLENGTH;
          pDMode^.dmPaperSize := DMPAPER_USER;
          pDMode^.dmPaperLength := Value * 10;
          pDMode^.dmFields := pDMode^.dmFields or DMBIN_MANUAL;
          pDMode^.dmDefaultSource := DMBIN_MANUAL;
          GlobalUnlock(hDMode);
        end;
      end;
      Printer.PrinterIndex := Printer.PrinterIndex;
    end;procedure TRepBoKuanTongZhi.SetPaperWidth(Value: integer);
    var
      device:array[0..255] of char;
      driver:array[0..255] of char;
      port:  array[0..255] of char;
      hdmode: thandle;
      pdmode:PDEVMODE;
    begin
      //自定义纸张最小宽度76mm
      if Value < 76 then Value:=76;
      //自定义纸张最大宽度216mm
      if value>216 then value:=216;
      printer.PrinterIndex:=printer.printerindex;
      printer.GetPrinter(device,driver,port,hdmode);
      if hdmode<>0 then
      begin
        pdmode:=globallock(hdmode);
        if pdmode<>nil then
        begin
          pDMode^.dmFields := pDMode^.dmFields or DM_PAPERSIZE or DM_PAPERWIDTH;
          pDMode^.dmPaperSize := DMPAPER_USER;
          //将毫米单位转换为0.1mm单位
          pDMode^.dmPaperWidth := Value * 10;
          pDMode^.dmFields := pDMode^.dmFields or DMBIN_MANUAL;
          pDMode^.dmDefaultSource := DMBIN_MANUAL;
          GlobalUnlock(hDMode);
        end;
      end;
      Printer.PrinterIndex := Printer.PrinterIndex;
    end;
      

  3.   


    procedure TRepBoKuanTongZhi.showme(shoulihao: string);
    var
      datetime1:tdatetime;
      vyear,vmonth,vday:word;
      value,vkey:string;//拨款的总额,以及本次拨款的分解值
      bencivalue:integer;//本次数量
    begin
      printlog:=0;
      adoquery1.Connection:=adoconn.getconn('fz_fp');
      adoquery2.Connection:=adoconn.getconn('fz_fp');
      adoquery1.close;
      adoquery1.SQL.text:=format('select * from fz_fp where fp_id=''%s'' ',[shoulihao]);
      adoquery1.Open;
      adoquery2.close;
      adoquery2.SQL.text:=format('select * from FZ_FP_THD where T_fp_id=''%s'' ',[shoulihao]);
      adoquery2.Open;
      datetime1:=adoquery2.fieldbyname('T_fp_date').asdatetime;
      decodedate(datetime1,vyear,vmonth,vday);
      while not adoquery2.eof do
      begin
        //value:=floattostr(adoquery1.fieldbyname('第一次拨款').asfloat+adoquery1.fieldbyname('第二次拨款').asfloat+adoquery1.fieldbyname('第三次拨款').asfloat);
        Printer.BeginDoc;
       //以下是你要所要追加打印的位置,
        printtext(28,34,adoquery2.fieldbyname('T_fp_dw').asstring,'filename');     //28是x轴的,单位是毫米,
                                          //34是y轴,单位也是毫米 
        PrintText(105, 38,inttostr(vyear),'filename');
        PrintText(122, 38,inttostr(vmonth),'filename');
        PrintText(135, 38,inttostr(vday),'filename');
        printText(28, 39,adoquery2.fieldbyname('T_THDD').asstring,'filename');
        printlog:=1;    // 更改打印机字体属性!  1 T_THDD
        //printtext(119,25,adoquery2.fieldbyname('T_id').asstring,'filename');
        PrintText(35, 46,adoquery2.fieldbyname('T_fp_cdpmjgg').asstring, 'filename');
        PrintText(102, 46,adoquery2.fieldbyname('T_fp_no').asstring, 'filename');
        bencivalue:=round(adoquery2.fieldbyname('T_ksl').asinteger);
        if bencivalue<>0 then                //个位
        begin
          vkey:=inttostr(bencivalue mod 10);
          if vkey<>'0' then
          begin
            PrintText(127, 54,conversion(vkey)+adoquery2.fieldbyname('T_fp_ypdw').asstring, 'filename');
          end
          else
            PrintText(127, 54,'零'+adoquery2.fieldbyname('T_fp_ypdw').asstring, 'filename');
          bencivalue:=bencivalue div 10;
        end
        else
        begin
          PrintText(127, 54,'零', 'filename');
        end;    if bencivalue<>0 then                      //十位
        begin
          vkey:=inttostr(bencivalue mod 10);
          if vkey<>'0' then
          begin
            PrintText(112, 54,conversion(vkey), 'filename');
          end
          else
            PrintText(112, 54,'零', 'filename');
          bencivalue:=bencivalue div 10;
        end
        else
          PrintText(112, 54,'零', 'filename');
        if bencivalue<>0 then                      //百位
        begin
          vkey:=inttostr(bencivalue mod 10);
          if vkey<>'0' then
          begin
            PrintText(96, 54,conversion(vkey), 'filename');
          end
          else
            PrintText(96, 54,'零', 'filename');
          bencivalue:=bencivalue div 10;
        end
        else
          PrintText(96, 54,'零', 'filename');    if bencivalue<>0 then               //千位
        begin
          vkey:=inttostr(bencivalue mod 10);
          if vkey<>'0' then
          begin
            PrintText(80, 54,conversion(vkey), 'filename');
          end
          else
            PrintText(80, 54,'零', 'filename');
          bencivalue:=bencivalue div 10;
        end
        else
          PrintText(80, 54,'零', 'filename');    if bencivalue<>0 then                 //万位
        begin
          vkey:=inttostr(bencivalue mod 10);
          if vkey<>'0' then
          begin
            PrintText(62, 54,conversion(vkey), 'filename');
          end
          else
            PrintText(62, 54,'零', 'filename');
          bencivalue:=bencivalue div 10;
        end
        else
          PrintText(62, 54,'零', 'filename');    if bencivalue<>0 then                        //十万
        begin
          vkey:=inttostr(bencivalue mod 10);
          if vkey<>'0' then
          begin
            PrintText(45, 54,conversion(vkey), 'filename');
          end
          else
            PrintText(45, 54,'零', 'filename');
          bencivalue:=bencivalue div 10;
        end
        else
          PrintText(45, 54,'零', 'filename');    if adoquery2.fieldbyname('T_fp_ypdw').asstring='吨' then
        begin
          PrintText(26, 61,adoquery2.fieldbyname('T_ksl').asstring+'公斤', 'filename');
        end
        else if adoquery2.fieldbyname('T_fp_ypdw').asstring='公斤' then
        begin
          PrintText(26, 61,adoquery2.fieldbyname('T_ksl').asstring+'公斤', 'filename')
        end
        else 
          PrintText(26, 61,adoquery2.fieldbyname('T_ksl').asstring+'升', 'filename');
        if adoquery1.fieldbyname('fp_pfj').AsInteger<>0 then
        begin
          printtext(70,61,adoquery1.fieldbyname('fp_pfj').asstring,'filename');
        end
        else if adoquery1.fieldbyname('fp_lsj').AsInteger<>0 then
        begin
          printtext(70,61,adoquery1.fieldbyname('fp_lsj').asstring,'filename');
        end
        else
        begin
           printtext(70,61,adoquery1.fieldbyname('fp_dbj').asstring,'filename');
        end;
        printtext(130,61,adoquery2.fieldbyname('T_QiXian').asstring+'天','filename');
        printtext(20,71,adoquery2.fieldbyname('T_memo').asstring,'filename');
        printlog:=0;
        Printer.EndDoc;    adoquery2.Next;    tmpadoquery.Close;
        tmpadoquery.SQL.text := format('update fz_fp_thd set T_print=1 where T_fp_id=''%s'' ',[shoulihao]);
        tmpadoquery.ExecSQL ;
      end;end;
    function TRepBoKuanTongZhi.VPointsPerInch: Integer;  //取得纵向方向每英寸打印机的光栅数
    begin
      Result:= GetDeviceCaps(Printer.Handle, LOGPIXELSY);
    end;function TRepBoKuanTongZhi.XPointToMm(Pos: Integer): Extended;  //横向点单位转换为毫米单位
    begin
      Result := Pos*25.4/HPointsPerInch;;
    end;function TRepBoKuanTongZhi.YPointToMm(Pos: Integer): Extended;
    begin
      Result := Pos*25.4/VPointsPerInch;
    end;procedure TRepBoKuanTongZhi.FormCreate(Sender: TObject);
    begin
        if not assigned(adoconn) then adoconn := tadoconn.create;
       adoquery1.Connection:=adoconn.GetConn('FZ_FP');
       adoquery2.connection:=adoconn.getconn('FZ_FP');
       tmpadoquery.connection:=adoconn.GetConn('FZ_FP');end;function TRepBoKuanTongZhi.conversion(key: string): string;
    var
      str1:string;
      i:integer;
    begin
      str1:='';
      for i:=1 to length(key)do
      begin
        if key='0' then   str1:=str1+'零';
        if key='1' then   str1:=str1+'壹';
        if key='2' then   str1:=str1+'贰';
        if key='3' then   str1:=str1+'叁';
        if key='4' then   str1:=str1+'肆';
        if key='5' then   str1:=str1+'伍';
        if key='6' then   str1:=str1+'陆';
        if key='7' then   str1:=str1+'柒';
        if key='8' then   str1:=str1+'捌';
        if key='9' then   str1:=str1+'玖';
      end;
      result:=str1;
    end;
      

  4.   

    上面两个帖子是连着的,因为太长,csdn不让一次发完!
      

  5.   

    数据库有一条打印了几条的记录是必要的,但是我觉得使用PRINTER的话,太麻烦了,QR 控件在打印之前会有一个事件。在这个事件里如果这次打印的不是需要印在纸上的,把相应的控件字体颜色设置成背景颜色(这样就不会打印)。如果是需要打印的,设置成你要的颜色,打印就OK了。
      

  6.   

    呵呵,我没有说清楚,在使用OR控件时,或者你干脆设置一个空白的BAND在要打印的记录上面,然后根据应该打印的位置来设定BAND的高度(如I*50等等),这样就可以打印在相应的位置了。打印完后在数据库中记录下这次打印的行数