长文本跨页测量

请先打开CaseStyudy目录下的文件"PDFCreator示例.Table"后再运行本节的示例代码。

上一节的文本测量示例还有有一个不足:一段文本只能绘制到同一个页面中。

有时文本需要跨页测量绘制,例如:

要实现文本跨页绘制,就需要分多次测量文本,所以需要用到MeasureString的这个语法:

MeasureString(text, font, width, sf, firstChar)

其中firstChar用于指定本次测量的起始位置。

我改写了上一节的lambda过程,可以完美地实现跨页测量和绘制文本,代码如下:

Dim DrawText =
Function
(tText As String, tFont As Font, tRect As RectangleF, tAlignment As stringAlignment, tUnderLine As Boolean, tDistance As Integer)
   
Dim tsf As New StringFormat
    tsf.Alignment = tAlignment
'设置对齐方式
    tRect.Height = tRect.Height + (rectPage.Bottom - tRect.Bottom)
'剩余空间全部分配给tRect
   
If tRect.Height <= 0 Then '如果没有剩余空间
        pdc.NewPage()
'则另起一页
        tRect = rectPage
   
End If
   
Dim nextChar As Integer = 0 '定义一个变量,用于记录开始绘制字符的位置,默认为0 ,也就是从第一个字符开始绘制
   
While nextChar < tText.Length - 1 '如果还有剩余字符没有绘制
       
Dim firstChar = nextChar '用于记录每次绘制的开始位置
        nextChar = pdc.DrawString(tText, tFont, color.Black, tRect, nextChar, tsf)
'注意DrawString返回的就是剩余内容的起始位置
       
If nextChar < tText.Length - 1 Then '如果还有剩余字符没有绘制
            pdc.NewPage()
'则另起一页
            tRect = rectPage
       
Else '如果已经绘制完毕
            tRect.Height = pdc.MeasureString(tText, tFont, trect.Width, tsf, firstChar).Height
'计算最后一次绘制字符串的高度
       
End If
   
End While
   
If tUnderLine Then '如果要绘制下划线
        pdc.DrawLine(pens.Black, tRect.Left, tRect.Bottom, tRect.Right, tRect.Bottom)
   
End If
    tRect.Offset(0, trect.Height + tDistance)
'移到下一个内容的起始位置
   
Return tRect '返回tRect
End
Function  

示例

下面是完整的测试代码,请在命令窗口测试执行:

Dim file As String = "c:\temp\test.pdf"
Dim
pdc As New PDFCreator()
pdc.PaperKind = Drawing.Printing.PaperKind.B5

Dim
rectPage As RectangleF = pdc.PageRectangle()
rectPage.Inflate( - 72, - 72)
'设置页边距为72磅,也就是2.54厘米
'用于测量、定位和绘制文本的lambda过程
Dim
DrawText =
Function
(tText As String, tFont As Font, tRect As RectangleF, tAlignment As stringAlignment, tUnderLine As Boolean, tDistance As Integer)
   
Dim tsf As New StringFormat
    tsf.Alignment = tAlignment
'设置对齐方式
    tRect.Height = tRect.Height + (rectPage.Bottom - tRect.Bottom)
'剩余空间全部分配给tRect
   
If tRect.Height <= 0 Then '如果没有剩余空间
        pdc.NewPage()
'则另起一页
        tRect = rectPage
   
End If
   
Dim nextChar As Integer = 0 '定义一个变量,用于记录开始绘制字符的位置,默认为0 ,也就是从第一个字符开始绘制
   
While nextChar < tText.Length - 1 '如果还有剩余字符没有绘制
       
Dim firstChar = nextChar '用于记录每次绘制的开始位置
        nextChar = pdc.DrawString(tText, tFont, color.Black, tRect, nextChar, tsf)
'注意DrawString返回的就是剩余内容的起始位置
       
If nextChar < tText.Length - 1 Then '如果还有剩余字符没有绘制
            pdc.NewPage()
'则另起一页
            tRect = rectPage
       
Else '如果已经绘制完毕
            tRect.Height = pdc.MeasureString(tText, tFont, trect.Width, tsf, firstChar).Height
'计算最后一次绘制字符串的高度
       
End If
   
End While
   
If tUnderLine Then '如果要绘制下划线
        pdc.DrawLine(pens.Black, tRect.Left, tRect.Bottom, tRect.Right, tRect.Bottom)
   
End If
    tRect.Offset(0, trect.Height + tDistance)
'移到下一个内容的起始位置
   
Return tRect '返回tRect
End
Function  
'
以下为内容绘制代码
Dim
rcCurrent As RectangleF = rectPage 'rcCurrent为绘制区域,我们将通过调整rcCurrent的位置和高度,来实现动态布局
Dim
fntName As New Font("微软雅黑", 10, FontStyle.Bold) '员工姓名字体
Dim
fntMemo As New Font("宋体", 10) '员工备注字体
For
Each r As Row In Tables("员工").Rows
   
Dim memo As String = r("备注")
    memo = memo & memo & memo
    rcCurrent = DrawText.Invoke(r(
"姓名").ToString(), fntName, rcCurrent, StringAlignment.Near, True, 5) '绘制员工姓名
    rcCurrent = DrawText.Invoke(memo, fntMemo, rcCurrent, StringAlignment.Near,
False, 25) '绘制员工备注
Next

pdc.Save(file)

Process.Start(file)


本页地址:http://www.foxtable.com/webhelp/topics/6088.htm