打印网页中特定内容的实现方法-----网络收集
由于工作的需要,要求打印网页。而且是网页中的指定内容。有点多次一举“可是这就是客户的需求!!~”(某高人语)。收集了两个比较合适的解决方法。
首先是用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(0, 0), 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


IDisposable 成员#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
}
}
以上demo不是本人编写
首先是用JAVASCRIPT,以下是函数
















应用时把要打印的内容放到<!--startprint-->和<!--endprint-->之间。
二是C# documment类和print类的实现:




























































































































































































































































































































































































































































































































































































































































































































































































