iTextSharp5.0頁首頁尾及Asp.net預覽的實現(PDF匯出)
阿新 • • 發佈:2019-01-25
iTextSharp5.0後沒有了HeaderFooter的類,導致頁首頁尾難以實現。經查資料後,發現可以通過PdfPageEventHelper裡面的OnEndPage來實現。先看看實現的效果圖。
頁首和頁尾部分使用PdfPTable來達成,下面是實現程式碼
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using iTextSharp.text; using iTextSharp.text.pdf; namespace ITextSharpTest { public class PDFBase : PdfPageEventHelper { #region 屬性 private String _fontFilePathForHeaderFooter = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "SIMHEI.TTF"); /// <summary> /// 頁首/頁尾所用的字型 /// </summary> public String FontFilePathForHeaderFooter { get { return _fontFilePathForHeaderFooter; } set { _fontFilePathForHeaderFooter = value; } } private String _fontFilePathForBody = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "SIMSUN.TTC,1"); /// <summary> /// 正文內容所用的字型 /// </summary> public String FontFilePathForBody { get { return _fontFilePathForBody; } set { _fontFilePathForBody = value; } } private PdfPTable _header; /// <summary> /// 頁首 /// </summary> public PdfPTable Header { get { return _header; } private set { _header = value; } } private PdfPTable _footer; /// <summary> /// 頁尾 /// </summary> public PdfPTable Footer { get { return _footer; } private set { _footer = value; } } private BaseFont _baseFontForHeaderFooter; /// <summary> /// 頁首頁尾所用的字型 /// </summary> public BaseFont BaseFontForHeaderFooter { get { return _baseFontForHeaderFooter; } set { _baseFontForHeaderFooter = value; } } private BaseFont _baseFontForBody; /// <summary> /// 正文所用的字型 /// </summary> public BaseFont BaseFontForBody { get { return _baseFontForBody; } set { _baseFontForBody = value; } } private Document _document; /// <summary> /// PDF的Document /// </summary> public Document Document { get { return _document; } private set { _document = value; } } #endregion public override void OnOpenDocument(PdfWriter writer, Document document) { try { BaseFontForHeaderFooter = BaseFont.CreateFont(FontFilePathForHeaderFooter, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); BaseFontForBody = BaseFont.CreateFont(FontFilePathForBody, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); Document = document; } catch (DocumentException de) { } catch (System.IO.IOException ioe) { } } #region GenerateHeader /// <summary> /// 生成頁首 /// </summary> /// <param name="writer"></param> /// <returns></returns> public virtual PdfPTable GenerateHeader(iTextSharp.text.pdf.PdfWriter writer) { return null; } #endregion #region GenerateFooter /// <summary> /// 生成頁尾 /// </summary> /// <param name="writer"></param> /// <returns></returns> public virtual PdfPTable GenerateFooter(iTextSharp.text.pdf.PdfWriter writer) { return null; } #endregion public override void OnEndPage(iTextSharp.text.pdf.PdfWriter writer, iTextSharp.text.Document document) { base.OnEndPage(writer, document); //輸出頁首 Header = GenerateHeader(writer); Header.TotalWidth = document.PageSize.Width - 20f; ///呼叫PdfTable的WriteSelectedRows方法。該方法以第一個引數作為開始行寫入。 ///第二個引數-1表示沒有結束行,並且包含所寫的所有行。 ///第三個引數和第四個引數是開始寫入的座標x和y. Header.WriteSelectedRows(0, -1, 10, document.PageSize.Height - 20, writer.DirectContent); //輸出頁尾 Footer = GenerateFooter(writer); Footer.TotalWidth = document.PageSize.Width - 20f; Footer.WriteSelectedRows(0, -1, 10, document.PageSize.GetBottom(50), writer.DirectContent); } } }
注:為了便於使用,做了一個PDFBase,後續只需要繼承即可。
注:程式碼對關鍵呼叫作了註釋。using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Text; using iTextSharp.text; using iTextSharp.text.pdf; namespace ITextSharpTest { /// <summary> /// PDF報表 /// </summary> public class PDFReport : PDFBase { #region 屬性 private int _pageRowCount = 12; /// <summary> /// 每頁的資料行數 /// </summary> public int PageRowCount { get { return _pageRowCount; } set { _pageRowCount = value; } } #endregion /// <summary> /// 模擬資料。實際時可能需要從資料庫或網路中獲取. /// </summary> private DataTable _dtSimulateData = null; private DataTable GenerateSimulateData() { DataTable dtSimulateData = new DataTable(); dtSimulateData.Columns.Add("Order", typeof(int));//序號 dtSimulateData.Columns.Add("No");//料號 dtSimulateData.Columns.Add("Name");//名稱 dtSimulateData.Columns.Add("Type");//型別 dtSimulateData.Columns.Add("GetTime");//領取時間 dtSimulateData.Columns.Add("BackTime");//歸還時間 dtSimulateData.Columns.Add("Remark");//備註 DataRow row = null; String[] types = new string[] { "文具", "輔料", "生活用品", "測試用具", "實體機" }; DateTime getDate = DateTime.Now; DateTime backDate = DateTime.Now; for (int i = 0; i < 100; i++) { row = dtSimulateData.NewRow(); row["Order"] = i + 1; row["No"] = (10000 + i + 1).ToString(); row["Name"] = Guid.NewGuid().ToString().Substring(0, 5);//造出隨機名稱 row["Type"] = types[(i * 3) % 5]; row["GetTime"] = getDate.AddDays(i).ToString("yyyy-MM-dd"); row["BackTime"] = ((i + i) % 3 == 0) ? "" : (backDate.AddDays(i + (i * 3) % 8).ToString("yyyy-MM-dd"));//造出沒有歸還時間的資料 row["Remark"] = "XXXXXXX"; dtSimulateData.Rows.Add(row); } return dtSimulateData; } #region GenerateHeader /// <summary> /// 生成頁首 /// </summary> /// <param name="fontFilePath"></param> /// <param name="pageNumber"></param> /// <returns></returns> public override PdfPTable GenerateHeader(iTextSharp.text.pdf.PdfWriter writer) { BaseFont baseFont = BaseFontForHeaderFooter; iTextSharp.text.Font font_logo = new iTextSharp.text.Font(baseFont, 30, iTextSharp.text.Font.BOLD); iTextSharp.text.Font font_header1 = new iTextSharp.text.Font(baseFont, 16, iTextSharp.text.Font.BOLD); iTextSharp.text.Font font_header2 = new iTextSharp.text.Font(baseFont, 12, iTextSharp.text.Font.BOLD); iTextSharp.text.Font font_headerContent = new iTextSharp.text.Font(baseFont, 12, iTextSharp.text.Font.NORMAL); float[] widths = new float[] { 55, 300, 50, 90, 15, 20, 15 }; PdfPTable header = new PdfPTable(widths); PdfPCell cell = new PdfPCell(); cell.BorderWidthBottom = 2; cell.BorderWidthLeft = 2; cell.BorderWidthTop = 2; cell.BorderWidthRight = 2; cell.FixedHeight = 35; cell.Phrase = new Phrase("LOGO", font_logo); cell.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER; cell.VerticalAlignment = iTextSharp.text.Element.ALIGN_CENTER; cell.PaddingTop = -1; header.AddCell(cell); cell = GenerateOnlyBottomBorderCell(2, iTextSharp.text.Element.ALIGN_LEFT); cell.Phrase = new Paragraph("PDF報表示例", font_header1); header.AddCell(cell); cell = GenerateOnlyBottomBorderCell(2, iTextSharp.text.Element.ALIGN_RIGHT); cell.Phrase = new Paragraph("日期:", font_header2); header.AddCell(cell); cell = GenerateOnlyBottomBorderCell(2, iTextSharp.text.Element.ALIGN_LEFT); cell.Phrase = new Paragraph("2015-07-27", font_headerContent); header.AddCell(cell); cell = GenerateOnlyBottomBorderCell(2, iTextSharp.text.Element.ALIGN_RIGHT); cell.Phrase = new Paragraph("第", font_header2); header.AddCell(cell); cell = GenerateOnlyBottomBorderCell(2, iTextSharp.text.Element.ALIGN_CENTER); cell.Phrase = new Paragraph(writer.PageNumber.ToString(), font_headerContent); header.AddCell(cell); cell = GenerateOnlyBottomBorderCell(2, iTextSharp.text.Element.ALIGN_RIGHT); cell.Phrase = new Paragraph("頁", font_header2); header.AddCell(cell); return header; } #region GenerateOnlyBottomBorderCell /// <summary> /// 生成只有底邊的cell /// </summary> /// <param name="bottomBorder"></param> /// <param name="horizontalAlignment">水平對齊方式<see cref="iTextSharp.text.Element"/></param> /// <returns></returns> private PdfPCell GenerateOnlyBottomBorderCell(int bottomBorder, int horizontalAlignment) { PdfPCell cell = GenerateOnlyBottomBorderCell(bottomBorder, horizontalAlignment, iTextSharp.text.Element.ALIGN_BOTTOM); cell.PaddingBottom = 5; return cell; } /// <summary> /// 生成只有底邊的cell /// </summary> /// <param name="bottomBorder"></param> /// <param name="horizontalAlignment">水平對齊方式<see cref="iTextSharp.text.Element"/></param> /// <param name="verticalAlignment">垂直對齊方式<see cref="iTextSharp.text.Element"/</param> /// <returns></returns> private PdfPCell GenerateOnlyBottomBorderCell(int bottomBorder, int horizontalAlignment, int verticalAlignment) { PdfPCell cell = GenerateOnlyBottomBorderCell(bottomBorder); cell.HorizontalAlignment = horizontalAlignment; cell.VerticalAlignment = verticalAlignment; ; return cell; } /// <summary> /// 生成只有底邊的cell /// </summary> /// <param name="bottomBorder"></param> /// <returns></returns> private PdfPCell GenerateOnlyBottomBorderCell(int bottomBorder) { PdfPCell cell = new PdfPCell(); cell.BorderWidthBottom = 2; cell.BorderWidthLeft = 0; cell.BorderWidthTop = 0; cell.BorderWidthRight = 0; return cell; } #endregion #endregion #region GenerateFooter public override PdfPTable GenerateFooter(iTextSharp.text.pdf.PdfWriter writer) { BaseFont baseFont = BaseFontForHeaderFooter; iTextSharp.text.Font font = new iTextSharp.text.Font(baseFont, 10, iTextSharp.text.Font.NORMAL); PdfPTable footer = new PdfPTable(3); AddFooterCell(footer, "審閱:", font); AddFooterCell(footer, "審批:", font); AddFooterCell(footer, "製表:張三", font); return footer; } private void AddFooterCell(PdfPTable foot, String text, iTextSharp.text.Font font) { PdfPCell cell = new PdfPCell(); cell.BorderWidthTop = 2; cell.BorderWidthRight = 0; cell.BorderWidthBottom = 0; cell.BorderWidthLeft = 0; cell.Phrase = new Phrase(text, font); cell.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER; foot.AddCell(cell); } #endregion #region ExportPDF /// <summary> /// 匯出PDF /// </summary> /// <param name="path">匯出路徑</param> public static void ExportPDF(String path) { PDFReport pdfReport = new PDFReport(); Document document = new Document(PageSize.A4.Rotate(), -90, -90, 60, 10);//此處設定的偏移量是為了加大頁面的可用範圍,可以使用預設. PdfWriter pdfWriter = PdfWriter.GetInstance(document, new FileStream(path, FileMode.Create)); pdfWriter.PageEvent = pdfReport;//此處一定要賦值,才能觸發頁首和頁尾的處理 document.Open(); pdfReport.AddBody(document); document.Close(); } /// <summary> /// 匯出PDF /// </summary> /// <param name="path">匯出路徑</param> public static byte[] ExportPDF() { PDFReport pdfReport = new PDFReport(); Document document = new Document(PageSize.A4.Rotate(), -90, -90, 60, 10);//此處設定的偏移量是為了加大頁面的可用範圍,可以使用預設. MemoryStream ms = new MemoryStream(); PdfWriter pdfWriter = PdfWriter.GetInstance(document, ms); pdfWriter.PageEvent = pdfReport;//此處一定要賦值,才能觸發頁首和頁尾的處理 document.Open(); pdfReport.AddBody(document); document.Close(); byte[] buff = ms.ToArray(); return buff; } #endregion #region AddBody private void AddBody(Document document) { _dtSimulateData = GenerateSimulateData(); int count = (_dtSimulateData.Rows.Count + (PageRowCount - 1)) / PageRowCount; for (int i = 0; i < count; i++) { AddBodySinglePage(i + 1); document.NewPage(); } } private void AddBodySinglePage(int pageNumber) { BaseFont baseFont = BaseFontForBody; iTextSharp.text.Font font_columnHeader = new iTextSharp.text.Font(baseFont, 11f, iTextSharp.text.Font.BOLD); iTextSharp.text.Font font_contentNormal = new iTextSharp.text.Font(baseFont, 9.5f, iTextSharp.text.Font.NORMAL); iTextSharp.text.Font font_contentSmall = new iTextSharp.text.Font(baseFont, 8f, iTextSharp.text.Font.NORMAL); int columnCount = 6;//此處是為了當列數很多時,便於迴圈生成所要的列寬比例 float[] widths = new float[columnCount]; for (int i = 0; i < columnCount; i++) { widths[i] = 1; } //需要加寬的再進行額外處理 widths[3] = 2;//時間 widths[4] = 3;//備註 PdfPTable bodyTable = new PdfPTable(widths); bodyTable.SpacingBefore = 10;//與頭部的距離 AddBodyHeader(bodyTable, font_columnHeader); AddBodyContent(bodyTable, font_contentNormal, font_contentSmall, pageNumber); Document.Add(bodyTable); } #region AddBodyHeader /// <summary> /// 新增Body的列標題 /// </summary> /// <param name="document"></param> /// <param name="font_columnHeader"></param> private void AddBodyHeader(PdfPTable bodyTable, iTextSharp.text.Font font_columnHeader) { //採用Rowspan和Colspan來控制單元格的合併與拆分,類似於HTML的Table. AddColumnHeaderCell(bodyTable, "料號", font_columnHeader, 1, 2); AddColumnHeaderCell(bodyTable, "名稱", font_columnHeader, 1, 2); AddColumnHeaderCell(bodyTable, "種類", font_columnHeader, 1, 2); AddColumnHeaderCell(bodyTable, "時間", font_columnHeader, 2, 1);//表頭下還有兩列表頭 AddColumnHeaderCell(bodyTable, "備註", font_columnHeader, 1, 2, true, true); //時間 AddColumnHeaderCell(bodyTable, "領取", font_columnHeader); AddColumnHeaderCell(bodyTable, "歸還", font_columnHeader, true, true); } #endregion #region AddBodyContent Function /// <summary> /// 新增報表正文 /// </summary> /// <param name="bodyTable"></param> /// <param name="fontNormal">普通字型</param> /// <param name="fontSmall">小字型,當內容顯示不下,需要使用小字型來顯示時,可以使用.</param> /// <param name="pageNumber">頁碼。便於從資料庫中按頁拉取資料時使用.</param> public void AddBodyContent(PdfPTable bodyTable, iTextSharp.text.Font fontNormal, iTextSharp.text.Font fontSmall, int pageNumber) { String filterExpression = String.Format("Order>{0} AND Order<={1}", (pageNumber - 1) * PageRowCount, pageNumber * PageRowCount); DataRow[] rows = _dtSimulateData.Select(filterExpression); foreach (var row in rows) { AddBodyContentRow(bodyTable, fontNormal, fontSmall, row); } } private void AddBodyContentRow(PdfPTable bodyTable, iTextSharp.text.Font fontNormal, iTextSharp.text.Font fontSmall, DataRow row) { AddBodyContentCell(bodyTable, String.Format("{0}", row["No"]), fontNormal);//料號 AddBodyContentCell(bodyTable, String.Format("{0}", row["Name"]), fontNormal);//名稱 AddBodyContentCell(bodyTable, String.Format("{0}", row["Type"]), fontNormal);//種類 AddBodyContentCell(bodyTable, String.Format("{0}", row["GetTime"]), fontSmall, 1);//時間-領取 String backTime = String.Format("{0}", row["BackTime"]); AddBodyContentCell(bodyTable, backTime, fontSmall);//時間-歸還 AddBodyContentCell(bodyTable, String.Format("{0}", row["Remark"]), fontSmall, 2, true);//備註 AddBodyContentCell(bodyTable, (String.IsNullOrWhiteSpace(backTime)) ? "消耗品不需歸還" : "", fontSmall, 1);//時間-領取(下方說明) } private static void AddBodyContentCell(PdfPTable bodyTable, String text, iTextSharp.text.Font font, int rowspan = 2, bool needRightBorder = false) { PdfPCell cell = new PdfPCell(); float defaultBorder = 0.5f; cell.BorderWidthLeft = defaultBorder; cell.BorderWidthTop = 0; cell.BorderWidthRight = needRightBorder ? defaultBorder : 0; cell.BorderWidthBottom = defaultBorder; cell.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER; cell.VerticalAlignment = iTextSharp.text.Element.ALIGN_BASELINE; cell.Rowspan = rowspan; cell.PaddingBottom = 4; cell.Phrase = new Phrase(text, font); cell.FixedHeight = 18f; bodyTable.AddCell(cell); } #endregion #region AddColumnHeaderCell Function /// <summary> /// 新增列標題單元格 /// </summary> /// <param name="table">表格行的單元格列表</param> /// <param name="header">標題</param> /// <param name="font">欄位</param> /// <param name="colspan">列空間</param> /// <param name="rowspan">行空間</param> /// <param name="needLeftBorder">是否需要左邊框</param> /// <param name="needRightBorder">是否需要右邊框</param> public void AddColumnHeaderCell(PdfPTable table, String header, iTextSharp.text.Font font, int colspan, int rowspan, bool needLeftBorder = true, bool needRightBorder = false) { PdfPCell cell = GenerateColumnHeaderCell(header, font, needLeftBorder, needRightBorder); if (colspan > 1) { cell.Colspan = colspan; } if (rowspan > 1) { cell.Rowspan = rowspan; } table.AddCell(cell); } /// <summary> /// 新增列標題單元格 /// </summary> /// <param name="table">表格</param> /// <param name="header">標題</param> /// <param name="font">欄位</param> /// <param name="needLeftBorder">是否需要左邊框</param> /// <param name="needRightBorder">是否需要右邊框</param> public void AddColumnHeaderCell(PdfPTable table, String header, iTextSharp.text.Font font, bool needLeftBorder = true, bool needRightBorder = false) { PdfPCell cell = GenerateColumnHeaderCell(header, font, needLeftBorder, needRightBorder); table.AddCell(cell); } #endregion #region GenerateColumnHeaderCell /// <summary> /// 生成列標題單元格 /// </summary> /// <param name="header">標題</param> /// <param name="font">欄位</param> /// <param name="needLeftBorder">是否需要左邊框</param> /// <param name="needRightBorder">是否需要右邊框</param> /// <returns></returns> private PdfPCell GenerateColumnHeaderCell(String header, iTextSharp.text.Font font, bool needLeftBorder = true, bool needRightBorder = false) { PdfPCell cell = new PdfPCell(); float border = 0.5f; cell.BorderWidthBottom = border; if (needLeftBorder) { cell.BorderWidthLeft = border; } else { cell.BorderWidthLeft = 0; } cell.BorderWidthTop = border; if (needRightBorder) { cell.BorderWidthRight = border; } else { cell.BorderWidthRight = 0; } cell.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER; cell.VerticalAlignment = iTextSharp.text.Element.ALIGN_BASELINE; cell.PaddingBottom = 4; cell.Phrase = new Phrase(header, font); return cell; } #endregion #endregion } }
Asp.net中的呼叫
public partial class _default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { byte[] buff = PDFReport.ExportPDF(); Response.ContentType = "application/pdf"; Response.BinaryWrite(buff); } } }
WinForm中的呼叫
private void btnExportPdf_Click(object sender, EventArgs e)
{
try
{
String path = textBoxPath.Text;
if (String.IsNullOrWhiteSpace(path))
{
MessageBox.Show("請輸入路徑");
return;
}
if (!Directory.Exists(Path.GetDirectoryName(path)))
{
MessageBox.Show("指定的目錄不存在");
return;
}
if (".PDF" != Path.GetExtension(path).ToUpper())
{
path = path + ".pdf";
}
PDFReport.ExportPDF(path);
MessageBox.Show("匯出成功");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
原始碼下載http://download.csdn.net/detail/xxdddail/8943371
轉載請註明出處http://blog.csdn.net/xxdddail/article/details/47128319