我現在用Printer.Canvas的列出來的格式是:
料號     品名規格       數量     單位    交貨日期
0001     ****1 ***AAA     1       PCS    ********
0002         ****2  ***BBB        1           PCS        ********我想它顯示成
料號     品名規格       數量     單位    交貨日期
0001     ****1          1PCS                    ********
       ***AAA
0002         ****2                1PCS                    *********
             ***BBB在數據庫中的對應關係是:
料號   品名    規格    數量     單位     交貨日期
0001   ****1   ***AAA   1     PCS     2004/11/03
0002   ****C   ***BBB   100    PCS     2004/10/29也就是說
1:品名規格分兩欄,數量與單位合成一列,一頁列印15行後自動分頁。
2:怎樣設置紙張的大小,因為我的紙張是已印刷好的紙,不是標准的A4紙,這樣當列印第二頁時,又套不上 格式,每次只能打印一頁,不能連打,並且不能超過15行,
注明:在數據庫中我的品名,規格,數量,單位都是各占一個字段,在列印時,我想將品名,規格分兩列,數量單位合並成一行。如上面所示。我的數據源代碼如下:請幫忙修改現在是要將規格顯示在品名下面,並當規格超過列寬時自動換行。
procedure TfrmFullPrint01.Button6Click(Sender: TObject);
var
  S:string;
  lines:integer;
  X,Y:integer;
  ARect: TRect;
begin
      Y:=10;
      X:=10;
      while (not ADOQuery1.Eof) or Printer.Aborted do
      begin
        Application.ProcessMessages;
        S:= ADOQuery1.FieldByName('fallorder_code').AsString;
        Printer.canvas.textout(x,y,s);
        x:=x+10;//這行有錯提示為:{raised exception class EPrinter with message 'Printer is not currently Printing':process stopped use step or run to continue}        S:= ADOQuery1.FieldByName('fallorder_name').AsString;
        Lines := Printer.canvas.TextWidth(s) div 10;
        ARect := Rect(X,y,X + 10, Y+LineHeight*Lines);
        DrawText(Printer.Canvas.Handle,PChar(S),-1, ARect, DT_WORDBREAK);
        x := X + 10;        if Y + LineHeight > Printer.PageHeight then
        begin
          AmountPrinted := 0;
          if not Printer.Aborted then
            Printer.NewPage;
          PrintHeader;
        end else
        begin
          Y := Y + lineHeight * lines;
        end;
        ADOQuery1.Next;
      end;
end;

解决方案 »

  1.   

    唉。
    你用一循环直接控制就可以了。
    比如:
    var
      i:Integer;
      Sum:Integer;
    begin  
      for i:=0 to Count do 
        begin
          Sum:=Sum+Higth;
          Printer.canvas.textout(X,Y,'asdf');//也是打印第一列;
          ................................
          Printer.canvas.textout(X+Higth,Y,'asdf');//这个就是打印你所要的第二行;
        end;
    end;这样的意思就是在一个循环里,同时要打两条,就是你的
    0001     ****1          1PCS                    ********
           ***AAA
    如此循环打印完所有的资料。多想想吧。
      

  2.   

    S:= ADOQuery1.FieldByName('fallorder_code').AsString;
        Printer.canvas.textout(x,y,s);
        x := x + 10; //這行有錯提示為:{raised exception class EPrinter 
                     //with message 'Printer is not currently Printing'
                     //:process stopped use step or run to continue}
                     
       //*********************************************
      注意上面的X,是个普通变量,不会错的,错的是光标所在行的前一行,就是
      Printer.canvas.textout(x,y,s);检查你的打印机是否正常
      另外,这个10是根据宽度得到的,你应该根据纸张大小和S的长度设定个合适的值.
       **********************************************//
            
     其实分行的关键在于计算内容的宽度,根据格子的宽度求得应该分多少行,然后用计算出打印的范围,是个Rect,就可以用DrawText让他自动分行了,记得下一行的Y位置要做相应的调整.一个原理,给你一张纸,一支笔,你会怎么写,就让电脑怎么写好了,电脑只是不够智能,需要指定坐标,而人不需要.設置紙張的大小这个问题你可以到WWW.GOOGLE.COM 输入: 自定义纸张 Delphi 点搜索,有超过10000条信息,选你喜欢的用吧.CSDN上本来也有很多,但全文搜索这几天不好用.
      

  3.   

    还有,打印前要加上一句:Printer.BeginDoc;  //你没这句话才错的
    最后加上一句:Printer.EndDoc;              //这样才把数据真正发给打印机。
      

  4.   

    miky(miky) ( ):謝謝你的指點,可我用
    var
      S,s1,s2:string;
      lines:integer;
      X,Y:integer;
      ARect: TRect;
    begin
          Printer.BeginDoc;
          Y:=150;//你自己取合适的?值;x,y?每??出的坐?
          X:=100;
          while (not ADOQuery1.Eof) do //or Printer.Aborted do
          begin
     begin        S:= ADOQuery1.FieldByName('fallorder_code').AsString;
            S1:= ADOQuery1.FieldByName('fallorder_name').AsString;
            S2:= ADOQuery1.FieldByName('fallorder_num').AsString;
            Printer.canvas.textout(x+100,y,s);
            Printer.canvas.textout(x+100,y+100,s1);
            Printer.canvas.textout(x+100,y+200,s2); 
            x:=x+100;
            S:= ADOQuery1.FieldByName('fallorder_dec').AsString;
            Lines := Printer.canvas.TextWidth(s) div 10;
            ARect := Rect(X,y,X+100, Y+LineHeight*Lines);
            DrawText(Printer.Canvas.Handle,PChar(S),-1, ARect, DT_WORDBREAK);
            x := X + 100;
            if Y + LineHeight > Printer.PageHeight then
            begin
              AmountPrinted := 0;
              if not Printer.Aborted then
                Printer.NewPage;
              PrintHeader;
            end else
            begin
              Y := Y + lineHeight * lines;
            end;
            ADOQuery1.Next;
          end;
          Printer.EndDoc;
    它打錢出來的是
    料號 ***1   ***2  ***3   ....
    品名  retr     wert     rtwrt   .....
    規格  ****    *****     *****   .....
    數量 1    100    1000  ....
    而不是我想要的
    料號    品名規格   數量
    ****1    retr      1
                ******
    這是為什麼,我對這個不是很熟悉,你能給我修改一下上面的代碼嗎?你做起來那麼簡單,可我寫起來總覺得很困難。真不愧是一級紅星,請多指教,謝謝!
      

  5.   

    這裡面也沒什麼算法啊,就是控制X,Y坐標,況且Printer.canvas.textout(x:integer,y:integer,s:string);坐標順序都已定義好,為什麼列印出來就孌了?我真是不得其解,還請指教。
      

  6.   

    就是你是怎么读那些数据出来的?给思路又不看。你用一循环直接控制就可以了。
    比如:
    var
      i:Integer;
      Sum:Integer;
    begin  
      for i:=0 to Count do 
        begin
          Sum:=Sum+Higth;
          Printer.canvas.textout(X,Y,'asdf');//也是打印第一列;
          ................................
          Printer.canvas.textout(X+Higth,Y,'asdf');//这个就是打印你所要的第二行;
        end;
    end;这样的意思就是在一个循环里,同时要打两条,就是你的
    0001     ****1          1PCS                    ********
           ***AAA
    如此循环打印完所有的资料。
      

  7.   

    ksaiy(消失在人海-喜欢昆明的花):很感謝你的指點,也許是我這個列印太復雜,現還想請教你一個問題,分行後'規格'***A有300個字,而表格只能寫入28個字,我想要它自動分行,我試用以下代碼用API來自動分行但沒有作用,代碼如下:
        Printer.Canvas.Font.Name:='宋体';
            Printer.Canvas.Font.Size:=12;
            Printer.canvas.textout(X,Y,s);
            Printer.canvas.textout(X+420,Y,s1);
            Printer.canvas.textout(X+420,Y+60,s2);//這條語句是用來列印規格的,是寫在下在還是寫在這裡
            Printer.canvas.textout(X+1300,Y+30,s3+s4);
            Printer.canvas.textout(X+2150,Y+30,s5);
            Printer.canvas.textout(X+2500,Y+30,s6);
            S:= ADOQuery1.FieldByName('fallorder_dec').AsString;
            Lines := Printer.canvas.TextWidth(s2) div 880;
            ARect := Rect(X,y+120,X+420,Y+LineHeight*Lines);
            DrawText(Printer.Canvas.Handle,PChar(S),-1, ARect, DT_WORDBREAK);//這條語句是用來處動分行,下面是不是還有寫一條Printer.canvas.textout(),
    上面這段代碼是miky(miky) ( ) 給我的,我用他這方法試過沒用,所以來求助大家,請指教,謝謝!!
      

  8.   

    ksaiy(消失在人海-喜欢昆明的花)
    miky(miky) 
    讚謝兩位的幫助,問題基本得到解決,能和你們交個朋友嗎?我的QQ是:314464916 。
    謝謝!!!!!