打印网页中特定内容

来源:互联网 发布:手机淘宝店铺公告制作 编辑:程序博客网 时间:2024/05/16 07:07
由于工作的需要,要求打印网页。而且是网页中的指定内容。有点多次一举“可是这就是客户的需求!!~”(某高人语)。收集了两个比较合适的解决方法。
首先是用JAVASCRIPT,以下是函数
<script language="javascript" type="text/javascript">
<!--

function Button3_onclick() 
{
bdhtml
=
window.document.body.innerHTML;
 sprnstr
="<!--startprint-->"
;
 eprnstr
="<!--endprint-->"
;
 prnhtml
=bdhtml.substr(bdhtml.indexOf(sprnstr)+17
);
 prnhtml
=prnhtml.substring(0
,prnhtml.indexOf(eprnstr));
 window.document.body.innerHTML
=
prnhtml;
 window.print();

}

</script>

应用时把要打印的内容放到<!--startprint-->和<!--endprint-->之间。
二是C# documment类和print类的实现:
using System;
using
 System.ComponentModel;
using
 System.Collections;
using
 System.Drawing;
using
 System.Drawing.Printing;
using
 System.Globalization;
using
 System.IO;
using Print =
 System.Drawing.Printing.PrintDocument;

namespace
 Sanxing.NdtReprot.Internal
{
    
/// <summary>
    
/// 表示专用于大量文本打印的对象,该对象将输出至打印机。
    
/// </summary>

    [Description("表示专用于大量文本打印的对象,该对象将输出至打印机。")]
    
internal sealed class
 TextPrintDocument : Print, IDisposable
    
{
        
#region 私有变量

        
private Font _printfont;
        
private
 Font _headerFooterFont;
        
private
 Pen _penHeaderFooterLine;
        
private
 PrintTextMode _printMode;
        
private bool
 _printLineNumbers;
        
private bool
 _printHeader;
        
private bool
 _printFooter;
        
private string
 _header;
        
private string
 _footer;
        
private
 TextReader _sr;
        
private
 ArrayList _buffer;
        
private bool
 _emptyBuffer;
        
private int
 _totalPageLines;
        
private int
 _currentPageLine;
        
private string
 _stringToPrint;
        
private int
 _currentPageNumber;
        
private int
 _currentLine;
        
private int
 _totalPrintedPages;
        
private const string DEFAULT_HEADER = "&n"
;
        
private const string DEFAULT_FOOTER = "&r&p"
;

        
private string[] _dateFormat = 
{
                                           
"dddd""ddd""dd""d""D""MMMM""MMM""MM""m""yyyy""yy""y""f"
,
                                           
"F""g""G""r""s""t""T""u""U"
,
                                       }
;

        
#endregion


        
#region 属性
        
        
/// <summary>
        
/// 设置要从中独取打印文本的 <see cref="Stream"/> 对象。
        
/// </summary>

        [Category("内容"), Description("设置要从中独取打印文本的数据流。")]
        
internal
 Stream ContentStream
        
{
            
set

            
{
                
if(value != null
)
                    _sr 
= new
 StreamReader(value);
            }

        }


        
/// <summary>
        
/// 获取或设置打印内容文本的字体。
        
/// </summary>

        [Category("内容"), Description("获取或设置打印内容文本的字体。")]
        
internal
 Font BodyFont
        
{
            
get return _printfont; }

            
set { _printfont = value; }
        }

        
        
/// <summary>
        
/// 获取或设置打印页眉页脚文本的字体。
        
/// </summary>

        [Category("内容"), Description("获取或设置打印页眉页脚文本的字体。")]
        
internal
 Font HeaderFooterFont
        
{
            
get return _headerFooterFont; }

            
set { _headerFooterFont = value; }
        }


        
/// <summary>
        
/// 获取或设置打印模式。
        
/// </summary>

        [Category("内容"), Description("获取或设置打印模式。"), DefaultValue(PrintTextMode.WrapText)]
        
internal
 PrintTextMode PrintMode
        
{
            
get return _printMode; }

            
set { _printMode = value; }
        }


        
/// <summary>
        
/// 获取或设置每页打印的行数。
        
/// </summary>

        [Category("内容"), Description("获取或设置每页打印的行数。")]
        
internal bool
 PrintLineNumber
        
{
            
get return _printLineNumbers; }

            
set { _printLineNumbers = value; }
        }


        
/// <summary>
        
/// 获取或设置一个值,该值指示是否打印页眉部分。
        
/// </summary>

        [Category("内容"), Description("获取或设置一个值,该值指示是否打印页眉部分。"), DefaultValue(false)]
        
internal bool
 PrintHeader
        
{
            
get return _printHeader; }

            
set { _printHeader = value; }
        }


        
/// <summary>
        
/// 获取或设置一个值,该值指示是否打印页脚部分。
        
/// </summary>

        [Category("内容"), Description("获取或设置一个值,该值指示是否打印页脚部分。"), DefaultValue(false)]
        
internal bool
 PrintFooter
        
{
            
get return _printFooter; }

            
set { _printFooter = value; }
        }


        
/// <summary>
        
/// 获取或设置要进行打印的文本。
        
/// </summary>

        [Category("内容"), Description("获取或设置要进行打印的文本。")]
        
internal string
 Text
        
{
            
get return _stringToPrint; }

            
set { _stringToPrint = value; }
        }


        
/// <summary>
        
/// 获取或设置要打印在页眉部分的文本。
        
/// </summary>

        [Description("获取或设置要打印在页眉部分的文本。"), DefaultValue(""), Category("内容")]
        
internal string
 Header
        
{
            
get return _header; }

            
set { _header = value; }
        }


        
/// <summary>
        
/// 获取或设置要打印在页脚部分的文本。
        
/// </summary>

        [Category("内容"), Description("获取或设置要打印在页脚部分的文本。"), DefaultValue("")]
        
internal string
 Footer
        
{
            
get return _footer; }

            
set { _footer = value; }
        }


        
#endregion


        
#region 构造器
        
        
/// <summary>
        
/// 使用默认值初始化 <b>TextPrintDocument</b> 类的新实例。
        
/// </summary>

        public TextPrintDocument() : base()
        
{
            _sr 
= null
;
            _stringToPrint 
= string
.Empty;
            _penHeaderFooterLine 
=
 Pens.Black;
            _header 
=
 DEFAULT_HEADER;
            _footer 
=
 DEFAULT_FOOTER;
        }


        
/// <summary>
        
/// 使用内容流以及字体初始化<b>TextPrintDocument</b> 类的新实例。
        
/// </summary>

        
/// <param name="Stream"></param>
        
/// <param name="BodyFont"></param>

        public TextPrintDocument(Stream Stream, Font BodyFont) :base()
        
{
            
if(Stream == null
)
                
throw new ArgumentNullException("Stream"
);
            _sr 
= new
 StreamReader(Stream);
            
if (BodyFont == null
)
                _printfont 
= new Font("宋体"3.5f
, FontStyle.Regular, GraphicsUnit.Millimeter);
            
else

                _printfont 
= BodyFont;
            _stringToPrint 
= string
.Empty;
            _penHeaderFooterLine 
=
 Pens.Black;
            _header 
=
 DEFAULT_HEADER;
            _footer 
=
 DEFAULT_FOOTER;
        }


        
/// <summary>
        
/// 
        
/// </summary>

        
/// <param name="PrintText"></param>
        
/// <param name="BodyFont"></param>

        public TextPrintDocument(string PrintText, Font BodyFont)
            : 
base
()
        
{
            
if(PrintText == null || PrintText == string
.Empty)
                
throw new ArgumentNullException("PrintText"
);
            _stringToPrint 
=
 PrintText;
            _sr 
= null
;
            
if (BodyFont == null
)
                _printfont 
= new Font("宋体"3.5f
, FontStyle.Regular, GraphicsUnit.Millimeter);
            
else

                _printfont 
= BodyFont;
            _penHeaderFooterLine 
=
 Pens.Black;
            _header 
=
 DEFAULT_HEADER;
            _footer 
=
 DEFAULT_FOOTER;
        }


        
#endregion


        
#region 方法

        
/// <summary>
        
/// 在处理打印内容前,执行必要操作。
        
/// </summary>

        
/// <param name="e"></param>

        protected override void OnBeginPrint(PrintEventArgs e)
        
{
            
base
.OnBeginPrint(e);
            
if (_sr == null && _stringToPrint == string
.Empty)
                
throw new InvalidOperationException("没有发现要进行打印处理的文档或数据流。"
);
            
// 检查是否有文本,有就生成读取器。

            if (_stringToPrint != string.Empty)
                _sr 
= new
 StringReader(_stringToPrint);
            
// 检查页眉页脚的字体

            if (_headerFooterFont == null)
                _headerFooterFont 
=
 _printfont;
            _currentPageNumber 
= 0
;
            _totalPrintedPages 
= 0
;
            _currentLine 
= 1
;
        }


        
/// <summary>
        
/// 打印完毕后,执行必要操作。
        
/// </summary>

        
/// <param name="e"></param>

        protected override void OnEndPrint(PrintEventArgs e)
        
{
            
base
.OnEndPrint(e);
            
if(_sr != null
)
                _sr.Close();
            _totalPrintedPages 
=
 _currentPageNumber;
        }


        
/// <summary>
        
/// 在打印前,生成打印内容。
        
/// </summary>

        
/// <param name="e"></param>

        protected override void OnPrintPage(PrintPageEventArgs e)
        
{
            
base
.OnPrintPage(e);
            Graphics gfx 
=
 e.Graphics;
            PageSettings pageset 
= DefaultPageSettings; // 页面设置

            float printAreaHeight = pageset.PaperSize.Height - (pageset.Margins.Top + pageset.Margins.Bottom);
            
float printAreaWidth = pageset.PaperSize.Width - (pageset.Margins.Left +
 pageset.Margins.Right);
            
float marginLeft =
 pageset.Margins.Left;
            
float marginTop =
 pageset.Margins.Top;
            
if
(DefaultPageSettings.Landscape)
            
{
                
float tmp =
 printAreaHeight;
                printAreaHeight 
=
 printAreaWidth;
                printAreaWidth 
=
 tmp;
            }

            
if(_buffer == null)
                _buffer 
= new
 ArrayList(_totalPageLines);
            
float charHeight =
 _printfont.GetHeight(gfx);
            
float headerFooterCharHeight =
 _headerFooterFont.GetHeight(gfx);
            
float headerFooterHeight = headerFooterCharHeight +
 charHeight;
            RectangleF rectHeader 
=

                
new RectangleF(marginLeft, marginTop, printAreaWidth, _printHeader ? headerFooterHeight : 0);
            RectangleF rectFooter 
=

                
new RectangleF(marginLeft, marginTop + printAreaHeight, printAreaWidth,
                               _printFooter 
? headerFooterHeight : 0
);
            
if(_printHeader) // 检查是否要输出页头

                DrawHeader(gfx, rectHeader);
            _totalPageLines 
= Convert.ToInt32((printAreaHeight - rectFooter.Height - rectHeader.Height) /
 charHeight);
            _currentPageLine 
= 0
;
            
if(_stringToPrint == null
)
                _stringToPrint 
=
 GetNextLine();
            
while((_currentPageLine <= _totalPageLines) && (_stringToPrint != null
))
            
{
                
float yPos = rectHeader.Bottom + (_currentPageLine *
 charHeight);
                
// Calculate printing rectangle area

                RectangleF rectTextLine = new RectangleF(marginLeft, yPos, printAreaWidth, charHeight);
                _stringToPrint 
=
 DrawTextLine(gfx, _stringToPrint, rectTextLine);
                PutNextLine(_stringToPrint);
                _currentPageLine
++
;
                _currentLine
++
;
                _stringToPrint 
=
 GetNextLine();
            }

            
if(_printFooter)
                DrawFooter(gfx, rectFooter);
            _currentPageNumber
++
;
            e.HasMorePages 
=
 HasMorePages();
        }


        
#endregion


        
#region 私有帮助器

        
/// <summary>
        
/// 获取下一行的文本内容。
        
/// </summary>

        
/// <returns></returns>

        private string GetNextLine()
        
{
            
string line = null
;
            
if(_printMode ==
 PrintTextMode.WrapText)
            
{
                
if(_buffer.Count == 0
)
                    line 
=
 _sr.ReadLine();
                
else

                
{
                    line 
= (string) _buffer[0
];
                    _buffer.RemoveAt(
0
);
                }

            }

            
else
            
{
                
if
(_emptyBuffer)
                
{
                    
if(_currentPageLine <
 _buffer.Count)
                    
{
                        line 
= (string
) _buffer[_currentPageLine];
                        _buffer[_currentPageLine] 
= null
;
                    }

                    
else
                    
{
                        
if(!
HasBufferChars())
                        
{
                            _buffer.Clear();
                            _emptyBuffer 
= false
;
                        }

                    }

                }

                
else
                
{
                    
if(_currentPageLine <=
 _totalPageLines)
                        line 
=
 _sr.ReadLine();
                    _emptyBuffer 
=
 HasBufferChars();

                    
if(line == null
)
                        _emptyBuffer 
=
 HasBufferChars();
                }

            }

            
return line;
        }


        
/// <summary>
        
/// 将处理过程推进到下一行。
        
/// </summary>

        
/// <param name="line"></param>

        private void PutNextLine(string line)
        
{
            
if(_printMode ==
 PrintTextMode.WrapText)
            
{
                
if(line.Length > 0
)
                
{
                    
if(_buffer.Count == 0
)
                        _buffer.Add(line);
                    
else

                        _buffer[
0= line;
                }

            }

            
else if(_printMode == PrintTextMode.BannerLike)
            
{
                
if(_currentPageLine <
 _buffer.Count)
                    _buffer[_currentPageLine] 
=
 line;
                
else

                    _buffer.Add(line);
            }

        }


        
private bool HasMorePages()
        
{
            
int moreChars = -1
;
            
try

            
{
                moreChars 
=
 _sr.Peek();
            }

            
catch(Exception)
            
{}

            
return (moreChars != -1|| _emptyBuffer;
        }


        
private bool HasBufferChars()
        
{
            
foreach(string str in
 _buffer)
            
{
                
if(str.Length > 0
)
                    
return true
;
            }

            
return false;
        }


        
private string DrawTextLine(Graphics gfx, string text, RectangleF rectangle)
        
{
            StringFormat fmt 
= new
 StringFormat();

            
if
(_printLineNumbers)
            
{
                Font fnLine 
= new
 Font(FontFamily.GenericMonospace, _printfont.Size);
                
string lineStr = String.Format("{0,4:G}"
, _currentLine);
                SizeF szfLine 
=
 gfx.MeasureString(lineStr, fnLine, rectangle.Size, fmt);
                gfx.DrawString(lineStr, fnLine, Brushes.Black, rectangle, fmt);
                rectangle.Inflate(
-(szfLine.Width + _printfont.Size), 0
);
            }

            
int charactersOnLine = GetLineBreakCharPosition(gfx, text, rectangle);
            gfx.DrawString(text, _printfont, Brushes.Black, rectangle, fmt);
            
return
 text.Substring(charactersOnLine);
        }


        
private int GetLineBreakCharPosition(Graphics gfx, string text, RectangleF rectangle)
        
{
            StringFormat fmt 
= new
 StringFormat(StringFormatFlags.MeasureTrailingSpaces);

            
int charactersOnLine = 0
;
            
int lines = 0
;
            SizeF sizeText 
= gfx.MeasureString(text, _printfont, rectangle.Size, fmt, out charactersOnLine, out
 lines);
            
string rem = text.Substring(0
, charactersOnLine);
            
if(rem.EndsWith(" "&& (charactersOnLine <
 text.Length))
            
{
                
string noSpaces = rem.TrimEnd(new Char[] {' '}
);
                
int nSpaces = rem.Length -
 noSpaces.Length;
                SizeF sizeChunk 
=

                    gfx.MeasureString(noSpaces, _printfont, rectangle.Size, fmt, 
out charactersOnLine, out lines);
                
string spacer =
 String.Empty;
                
while(sizeChunk.Width <=
 rectangle.Width)
                
{
                    spacer 
+= " "
;
                    sizeChunk 
= gfx.MeasureString(noSpaces + spacer, _printfont, new PointF(00
), fmt);
                }


                charactersOnLine 
+= spacer.Length - ((sizeChunk.Width > rectangle.Width) ? 1 : 0);
            }


            
return charactersOnLine;
        }


        
/// <summary>
        
/// 打印页眉。
        
/// </summary>

        
/// <param name="gfx"></param>
        
/// <param name="rectangle"></param>

        private void DrawHeader(Graphics gfx, RectangleF rectangle)
        
{
            StringFormat fmtHeader 
= new
 StringFormat();
            
string header = MakeHeaderFooterString(Header, ref
 fmtHeader);
            gfx.DrawString(header, _headerFooterFont, Brushes.Black, rectangle, fmtHeader);
            
float yPos = rectangle.Top + (_headerFooterFont.GetHeight(gfx) + 2
);
            
if(yPos <=
 rectangle.Bottom)
                gfx.DrawLine(_penHeaderFooterLine, rectangle.Left, yPos, rectangle.Right, yPos);
        }


        
/// <summary>
        
/// 打印页脚。
        
/// </summary>

        
/// <param name="gfx"></param>
        
/// <param name="rectangle"></param>

        private void DrawFooter(Graphics gfx, RectangleF rectangle)
        
{
            StringFormat fmtHeader 
= new
 StringFormat();
            
string header = MakeHeaderFooterString(Footer, ref
 fmtHeader);
            fmtHeader.LineAlignment 
|=
 StringAlignment.Far;
            gfx.DrawString(header, _headerFooterFont, Brushes.Black, rectangle, fmtHeader);
            
float yPos = rectangle.Bottom - (_headerFooterFont.GetHeight(gfx) + 2
);
            
if(yPos >=
 rectangle.Top)
                gfx.DrawLine(_penHeaderFooterLine, rectangle.Left, yPos, rectangle.Right, yPos);
        }


        
private string MakeHeaderFooterString(string template, ref StringFormat format)
        
{
            
string headerFooter =
 template;
            
int ix = headerFooter.IndexOf("&l"
);
            
if(ix != -1
)
            
{
                format.Alignment 
=
 StringAlignment.Near;
                headerFooter 
= headerFooter.Remove(ix, 2
);
            }


            ix 
= headerFooter.IndexOf("&r");
            
if(ix != -1
)
            
{
                format.Alignment 
=
 StringAlignment.Far;
                headerFooter 
= headerFooter.Remove(ix, 2
);
            }


            ix 
= headerFooter.IndexOf("&c");
            
if(ix != -1
)
            
{
                format.Alignment 
=
 StringAlignment.Center;
                headerFooter 
= headerFooter.Remove(ix, 2
);
            }

            headerFooter 
= headerFooter.Replace("&p", (_currentPageNumber + 1).ToString());
            headerFooter 
= headerFooter.Replace("&n"
, DocumentName);
            DateTime dt 
=
 DateTime.Now;
            ix 
= 0
;
            
while((ix = headerFooter.IndexOf("%")) != -1
)
            
{
                
bool found = false
;
                
for(int i = 0; i < _dateFormat.Length; i++
)
                
{
                    
string fmt = "%" +
 _dateFormat[i];
                    
if(headerFooter.Substring(ix, fmt.Length) ==
 fmt)
                    
{
                        
string date =
 dt.ToString(_dateFormat[i], DateTimeFormatInfo.InvariantInfo);

                        headerFooter 
=
 headerFooter.Remove(ix, fmt.Length);
                        headerFooter 
=
 headerFooter.Insert(ix, date);
                        found 
= true
;
                        
break
;
                    }

                }

                
if(!found)
                    headerFooter 
= headerFooter.Remove(ix, 1
);
            }

            
return headerFooter;
        }


        
#endregion


        
#region IDisposable 成员

        
/// <summary>
        
/// 移除由 <b>TextPrintDocument</b> 使用的所有托管资源。
        
/// </summary>

        public new void Dispose()
        
{
            Dispose(
true
);
        }


        
/// <summary>
        
/// 
        
/// </summary>

        
/// <param name="disposing"></param>

        protected override void Dispose(bool disposing)
        
{
            
if
(disposing)
            
{
                
lock(this
)
                
{
                    
if (_sr != null
)
                        _sr.Dispose();
                }

                GC.SuppressFinalize(
true);
            }

            
base.Dispose(disposing);
        }

        
        
/// <summary>
        
/// 供 <see cref="GC"/> 使用的清理托管资源的方法。
        
/// </summary>

        ~TextPrintDocument()
        
{
            Dispose(
false
);
        }


        
#endregion

    }


    
/// <summary>
    
/// 指定打印文本的模式。
    
/// </summary>

    internal enum PrintTextMode
    
{
        
/// <summary>
        
/// 换行文本。
        
/// </summary>

        WrapText,
        Truncate,
        BannerLike
    }

}

 
原创粉丝点击