如何把StringGrid所见即所得的样式直接打印出来?

PAOLO_TQ 2007-12-05 01:44:32
StringGrid生成后,个别的行和列都进行了调整
很多地方都进行了合并,所以并不是一个规则的表格
同时,有些合并了的单元格里面的字数很多,又因为StringGrid不能换行,
在显示的时候通过Canvas.TextOut()方式进行了换行
而且整个StringGrid通过DrawCells方法进行了上下左右的居中美化
但打印的时候这些效果都又恢复原样了
怎样才能把屏幕上显示的效果通过打印机打印出来呢?
我用的是AdvStringGrid控件包
最好不要通过FastReport等控件或者QReport等表来打印
有知道的侠客们能指点一下吗?
...全文
174 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
PAOLO_TQ 2008-01-16
  • 打赏
  • 举报
回复
多谢12楼的!
现在可以结贴了!
谢谢关注
flashtong 2007-12-12
  • 打赏
  • 举报
回复
回复楼上的,你可以仔细看看vcl的 forms 的4693行 到 4763行,我的是d7。

楼主,你的这个完全可以用 canvas打印出来的。在csdn搜了一个,思路可以,楼主看下;
procedure PrintGrid(sGrid: TStringGrid; sTitle: string);
var
X1, X2: Integer;
Y1, Y2: Integer;
TmpI: Integer;
F: Integer;
TR: TRect;
begin
Printer.Title := sTitle;
Printer.BeginDoc;
Printer.Canvas.Pen.Color := 0;
Printer.Canvas.Font.Name := 'Times New Roman';
Printer.Canvas.Font.Size := 12;
Printer.Canvas.Font.Style := [fsBold, fsUnderline];
Printer.Canvas.TextOut(0, 100, Printer.Title);
for F := 1 to sGrid.ColCount - 1 do begin
X1 := 0;
for TmpI := 1 to (F - 1) do
X1 := X1 + 5 * (sGrid.ColWidths[TmpI]);
Y1 := 300;
X2 := 0;
for TmpI := 1 to F do
X2 := X2 + 5 * (sGrid.ColWidths[TmpI]);
Y2 := 450;
TR := Rect(X1, Y1, X2 - 30, Y2);
Printer.Canvas.Font.Style := [fsBold];
Printer.Canvas.Font.Size := 7;
Printer.Canvas.TextRect(TR, X1 + 50, 350, sGrid.Cells[F, 0]);
Printer.Canvas.Font.Style := [];
for TmpI := 1 to sGrid.RowCount - 1 do begin
Y1 := 150 * TmpI + 300;
Y2 := 150 * (TmpI + 1) + 300;
TR := Rect(X1, Y1, X2 - 30, Y2);
Printer.Canvas.TextRect(TR, X1 + 50, Y1 + 50, sGrid.Cells[F, TmpI]);
end;
end;
Printer.EndDoc;
end;
byteh 2007-12-10
  • 打赏
  • 举报
回复
1、FDynAnalysisFrame.Plot1.Repaint; 这个是什么?
2、Img.Canvas.CopyRect(ARect, ASource, ARect)总提示我参数错误!
我用的是Img.Canvas.CopyRect(Grid1.ClientRect, Img.Canvas, Grid1.ClientRect);
或者 Img.Canvas.CopyRect(Img.ClientRect, Img.Canvas, Grid1.ClientRect);
都提示“参数错误”,不明白是怎么回事?

sorry,这是从我的代码里面粘过来的,供你参考,不能直接用的,不好意思!
如果是规矩的二维表,不行就放到Excel里面,执行个打印
你想都打印到一页?
sy_100000 2007-12-10
  • 打赏
  • 举报
回复
为什么大家这么喜欢拷屏打印的方式?我觉得这种打印效果未免太粗糙了吧?另外,VCL的Canvas用于打印图象,非常不乐观,因为有时候打印出来或者什么没有,或者就一个深色方块,这种情况,我经常遇到,很多资料有说明,也提出了各种解决方案。VCL的TForm的Print方法,就是拷屏打印的,但Borland自己都不乐意用Canvas方法来打印,可以打开Forms单元去看Borland是怎么打印Form的!
无条件为你 2007-12-08
  • 打赏
  • 举报
回复
你可以先把StringGrid里面的内容导入到Excel里面,然后在Excel里面调整后调用打印,这样的话,你也不用再编写打印代码了。

下面这段代码实现将StringGrid内容导入到.XLS


procedure stringGridtoExcell(stringgrid1:Tstringgrid);
var
eclApp,WorkBook:Variant;
xlsFileName:string;
l_row,l_col:integer;
begin
xlsFileName:='ex.xls';
try
//创建OLE对象Excel Application与 WorkBook
eclApp:=CreateOleObject('Excel.Application');
WorkBook:=CreateOleobject('Excel.Sheet');
except
ShowMessage('您的机器里未安装Microsoft Excel。');
Exit;
end;
try
workBook:=eclApp.workBooks.Add;
for l_row:=0 to stringgrid1.rowcount-1 do
begin
for l_col:=0 to stringgrid1.ColCount-1 do
begin
eclApp.cells[l_row+1,l_col+1]:=stringgrid1.cells[l_col,l_row];
end;
end;

form1.SaveDialog1.Filter:='Excel文件|*.xls';//上句可省略,只是作显示。
if not form1.SaveDialog1.Execute then exit;

WorkBook.saveas(form1.SaveDialog1.FileName);
//打印预览
eclApp.Visible:=true;
eclApp.WindowState := 2;
//再最大化
eclApp.WindowState := 1;
//退出Excel Application
//释放VARIANT变量
except
ShowMessage('不能正确操作Excel文件。可能是该文件已被其他程序打开, 或系统错误。');
WorkBook.close;
//释放VARIANT变量
// eclApp:=Unassigned;
end;
end;
oushengfen 2007-12-07
  • 打赏
  • 举报
回复
可以一页页进行打印,滚动条可以自己进行控制。
qiankun19851231 2007-12-07
  • 打赏
  • 举报
回复
可以入在一个临时表中.把这个临时表做为一个数据源进行打印
PAOLO_TQ 2007-12-07
  • 打赏
  • 举报
回复
非要用FastReport吗?
难道delphi自身实现不了这样的需求吗?
pilicat 2007-12-06
  • 打赏
  • 举报
回复
还是用FastReport吧。
PAOLO_TQ 2007-12-06
  • 打赏
  • 举报
回复
Thanks flashtong!不过这个方法我试过后没有办法满足要求,它对StringGrid的Scrollbar没有效果,只能将屏幕上显示出来的部分打印出来。
另外,用copyRect,怎么同时把握屏幕上出现的打印对话框都打印出来了,遮挡住了部分表格,不知道是什么问题?我把Canvas锁住了,还是会出现把对话框打印出来的问题!

也谢谢byteh,我试了试你的代码,总是编译通不过,存在两个问题没弄明白
1、FDynAnalysisFrame.Plot1.Repaint; 这个是什么?
2、Img.Canvas.CopyRect(ARect, ASource, ARect)总提示我参数错误!
我用的是Img.Canvas.CopyRect(Grid1.ClientRect, Img.Canvas, Grid1.ClientRect);
或者 Img.Canvas.CopyRect(Img.ClientRect, Img.Canvas, Grid1.ClientRect);
都提示“参数错误”,不明白是怎么回事?
3、用byteh你的这种方法,是不是也没有办法把表格完全打印到一张纸上呢?
我的所有的StringGrid都是比较长,用了VSrollBar上下滚动,但打印出来都可以在一张纸上放下。用了CopyRect后,总是只能打印可视部分的表格

不知道有没有办法解决呢?谢谢
byteh 2007-12-05
  • 打赏
  • 举报
回复
区域打印 , ARect是指定的TRect

if not PrintDialog.Execute then Exit;

Printer.BeginDoc;
Img := TImage.Create(nil);
try
OutputWidth := ARect.Right - ARect.Left;
OutputHeight := ARect.Bottom - ARect.Top;

Img.Width := Round(OutputWidth);
Img.Height := Round(OutputHeight);
FDynAnalysisFrame.Plot1.Repaint;
Img.Canvas.CopyRect(ARect, ASource, ARect);

AspectRatio := OutputWidth / OutputHeight;
if (OutputWidth < Printer.PageWidth) and (OutputHeight < Printer.PageHeight) then
begin
if OutputWidth < OutputHeight then
begin
OutputHeight := Printer.PageHeight;
OutputWidth := OutputHeight * AspectRatio;
end
else
begin
OutputWidth := Printer.PageWidth;
OutputHeight := OutputWidth / AspectRatio;
end
end;
if OutputWidth > Printer.PageWidth then
begin
OutputWidth := Printer.PageWidth;
OutputHeight := OutputWidth / AspectRatio;
end;
if OutputHeight > Printer.PageHeight then
begin
OutputHeight := Printer.PageHeight;
OutputWidth := OutputHeight * AspectRatio;
end;
Printer.Canvas.StretchDraw(Rect(0, 0, Trunc(OutputWidth), Trunc(OutputHeight)), Img.Picture.Graphic);
finally
Printer.EndDoc;
Img.Free;
end;
hui717 2007-12-05
  • 打赏
  • 举报
回复
学习了
flashtong 2007-12-05
  • 打赏
  • 举报
回复
用copyrect

uses
printers;

printer.Canvas.CopyRect(stringgrid1.ClientRect,stringgrid1.Canvas,stringgrid1.ClientRect);

//我试验过,肯定没有问题。
//不用任何的控件
//printer 的操作,具体看帮助。
//如果我提示能够帮助你,别忘了给点分。

5,392

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧