一个用itexsharp导出pdf ,并且页眉页码显示
之前有一次加班写一个导出PDF,需要有页眉页码等,于是就用itexsharp 导出,数据源用的是datatable 。 参考了博客园的其它文章https://www.cnblogs.com/sparkleDai/p/7604959.html
一个PDFBase.cs
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, 38, document.PageSize.Height - 40, writer.DirectContent); //输出页脚 Footer = GenerateFooter(writer); Footer.TotalWidth = document.PageSize.Width - 20f; Footer.WriteSelectedRows(0, -1, 10, document.PageSize.GetBottom(50), writer.DirectContent); } } }
一个PDFReport
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; using ITextSharpTest; namespace ITextSharpTest { /// <summary> /// PDF报表 /// </summary> public class PDFReport : PDFBase { #region 属性 private int _pageRowCount = 9; /// <summary> /// 每页的数据行数 /// </summary> public int PageRowCount { get { return _pageRowCount; } set { _pageRowCount = value; } } #endregion /// <summary> /// 数据 /// </summary> private DataTable _dtSimulateData = null; /// <summary> /// 总页数 /// </summary> private int _total = 0; /// <summary> /// 账单金额 /// </summary> private static decimal _totalAmount =0; /// <summary> /// 付款单位 /// </summary> private static string _hospital = ""; private static DateTime _ttt = new DateTime(); private static DateTime _aaa = new DateTime(); #region GenerateHeader /// <summary> /// 生成页眉 /// </summary> /// <param name="writer"></param> /// <returns></returns> public override PdfPTable GenerateHeader(iTextSharp.text.pdf.PdfWriter writer) { BaseFont baseFont = BaseFontForHeaderFooter; 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.NORMAL); iTextSharp.text.Font font_headerContent = new iTextSharp.text.Font(baseFont, 12, iTextSharp.text.Font.NORMAL); float[] widths = new float[] { 200,50, 90 }; 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.Rowspan = 3; iTextSharp.text.Image hgLogo = iTextSharp.text.Image.GetInstance(System.Web.HttpContext.Current.Server.MapPath(@"\Images\shishi\1234.png")); hgLogo.ScalePercent(40f); //图片比例 hgLogo.SetAbsolutePosition(80f, writer.PageSize.Height - 80f); hgLogo.Border = 0; cell.Image = hgLogo; cell.Border = 0; header.AddCell(cell); cell.Rowspan = 4; cell = GenerateOnlyBottomBorderCell(0, iTextSharp.text.Element.ALIGN_RIGHT); cell.Phrase = new Paragraph(" 付款单位:" + "\n\n" + "付款所属区间:", font_header2); header.AddCell(cell); cell = GenerateOnlyBottomBorderCell(0, iTextSharp.text.Element.ALIGN_LEFT); cell.Phrase = new Paragraph(_hospital + "\n\n" + _ttt.ToString("yyyy-MM-dd") + "至" + _aaa.ToString("yyyy-MM-dd"), font_header2); header.AddCell(cell); //一下仅仅是站位用的,, cell = GenerateOnlyBottomBorderCell(0, iTextSharp.text.Element.ALIGN_LEFT); cell.Phrase = new Paragraph("", font_headerContent); header.AddCell(cell); cell = GenerateOnlyBottomBorderCell(0, iTextSharp.text.Element.ALIGN_LEFT); cell.Phrase = new Paragraph("", font_headerContent); header.AddCell(cell); cell = GenerateOnlyBottomBorderCell(0, iTextSharp.text.Element.ALIGN_LEFT); cell.Phrase = new Paragraph("", font_headerContent); header.AddCell(cell); cell = GenerateOnlyBottomBorderCell(0, iTextSharp.text.Element.ALIGN_LEFT); cell.Phrase = new Paragraph("", font_headerContent); header.AddCell(cell); cell = GenerateOnlyBottomBorderCell(0, iTextSharp.text.Element.ALIGN_LEFT); cell.Phrase = new Paragraph("", font_headerContent); header.AddCell(cell); cell = GenerateOnlyBottomBorderCell(0, iTextSharp.text.Element.ALIGN_LEFT); cell.Phrase = new Paragraph("", font_headerContent); 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 = bottomBorder; 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(1); PdfPCell cell = new PdfPCell(); cell = GenerateOnlyBottomBorderCell(0, iTextSharp.text.Element.ALIGN_CENTER); cell.Phrase = new Paragraph("第 "+writer.PageNumber.ToString()+ " 页 共 "+ _total+" 页", font); footer.AddCell(cell); 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,DataTable dt) { 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,dt); document.Close(); } /// <summary> /// 导出PDF /// </summary> /// <param name="path">导出路径</param> public static byte[] ExportPDF(DataTable dt,string Hospital,DateTime ttt,decimal totalAmount) { string[] dataCol = GetColumnsByDataTable(dt); _hospital = Hospital; _totalAmount=totalAmount; _ttt = ttt; DateTime aaa = LastDayOfMonth(ttt); _aaa = aaa; PDFReport pdfReport = new PDFReport(); Document document = new Document(PageSize.A4.Rotate(), -60, -60, 110, 10);//此处设置的偏移量是为了加大页面的可用范围,可以使用默认. MemoryStream ms = new MemoryStream(); PdfWriter pdfWriter = PdfWriter.GetInstance(document, ms); pdfWriter.PageEvent = pdfReport;//此处一定要赋值,才能触发页眉和页脚的处理 document.Open(); pdfReport.AddBody(document,dt, dataCol); document.Close(); byte[] buff = ms.ToArray(); return buff; } #endregion #region AddBody private void AddBody(Document document,DataTable data,string[] dataCol) { _dtSimulateData = data; int count = (_dtSimulateData.Rows.Count + (PageRowCount - 1)) / PageRowCount; _total = count+1; for (int i = 0; i < count; i++) { AddBodySinglePage(i + 1, dataCol); document.NewPage(); } document.Add(GenerateHeaderzd("账单金额总计:" + _totalAmount.ToString())); } private void AddBodySinglePage(int pageNumber,string[] dataCol) { BaseFont baseFont = BaseFontForBody; iTextSharp.text.Font font_columnHeader = new iTextSharp.text.Font(baseFont, 14f, iTextSharp.text.Font.NORMAL); iTextSharp.text.Font font_contentNormal = new iTextSharp.text.Font(baseFont, 12f, iTextSharp.text.Font.NORMAL); iTextSharp.text.Font font_contentSmall = new iTextSharp.text.Font(baseFont, 8f, iTextSharp.text.Font.NORMAL); int columnCount = dataCol.Length;//此处是为了当列数很多时,便于循环生成所要的列宽比例 float[] widths = new float[columnCount]; for (int i = 0; i < columnCount; i++) { widths[i] = 1; } widths[3] = 3; PdfPTable bodyTable = new PdfPTable(widths); bodyTable.SpacingBefore = 10;//与头部的距离 float[] dw = new float[] { 480, 100 }; PdfPTable header = new PdfPTable(dw); PdfPCell cell = new PdfPCell(); cell = GenerateOnlyBottomBorderCell(0, iTextSharp.text.Element.ALIGN_LEFT); cell.Phrase = new Paragraph(" 这是一个名字", font_columnHeader); header.AddCell(cell); cell = GenerateOnlyBottomBorderCell(0, iTextSharp.text.Element.ALIGN_LEFT); cell.Phrase = new Paragraph("88888830", font_columnHeader); header.AddCell(cell); Document.Add(header); AddBodyHeader(bodyTable, font_columnHeader, dataCol); AddSinglePageData(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, Font font_columnHeader,string[] dataCol) { for (int i = 0; i < dataCol.Length; i++) { //循环获取列名 AddColumnHeaderCell(bodyTable, dataCol[i], font_columnHeader, 1, 2); } } #endregion #region AddBodyContent Function /// <summary> /// 添加对应每页的数据 /// </summary> /// <param name="bodyTable">表格</param> /// <param name="fontNormal">普通字体</param> /// <param name="fontSmall">小字体,当内容显示不下,需要使用小字体来显示时,可以使用.</param> /// <param name="pageNumber">页码</param> private void AddSinglePageData(PdfPTable bodyTable, iTextSharp.text.Font fontNormal, iTextSharp.text.Font fontSmall, int pageNumber) { int count = _dtSimulateData.Rows.Count;//数据总量 int startIndex = (pageNumber - 1) * PageRowCount;//开始索引 int endIndex = pageNumber * PageRowCount;//结束索引 int startIndex1 = count - startIndex;//下一页的开始索引 int surplusNumbers = count - endIndex;//剩下的数量 if (surplusNumbers > PageRowCount) { for (int i = startIndex; i < endIndex; i++) { AddBodyContent(bodyTable, fontNormal, fontSmall, i); } } else { if (surplusNumbers > 0) { for (int i = startIndex; i < endIndex; i++) { AddBodyContent(bodyTable, fontNormal, fontSmall, i); } } else { for (int i = startIndex; i < startIndex + startIndex1; i++) { AddBodyContent(bodyTable, fontNormal, fontSmall, i); } } } } public void AddBodyContent(PdfPTable bodyTable, iTextSharp.text.Font fontNormal, iTextSharp.text.Font fontSmall, int index) { DataRow row = _dtSimulateData.Rows[index]; for (int i = 0; i < row.Table.Columns.Count; i++) { AddBodyContentCell(bodyTable, String.Format("{0}", row[i]), fontNormal); } } private static void AddBodyContentCell(PdfPTable bodyTable,String text,iTextSharp.text.Font font,int rowspan = 2,bool needRightBorder = true) { 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 = 30; cell.UseAscender = true; cell.VerticalAlignment = Element.ALIGN_MIDDLE; 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 = true) { 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.FixedHeight = 30; cell.UseAscender = true; cell.VerticalAlignment = Element.ALIGN_MIDDLE; cell.PaddingBottom = 4; cell.Phrase = new Phrase(header, font); return cell; } #endregion #endregion #region 根据datatable获得列名 public static string[] GetColumnsByDataTable(DataTable dt) /// <summary> /// 根据datatable获得列名 /// </summary> /// <param name="dt">表对象</param> /// <returns>返回结果的数据列数组</returns> public static string[] GetColumnsByDataTable(DataTable dt) { string[] strColumns = null; if (dt.Columns.Count > 0) { int columnNum = 0; columnNum = dt.Columns.Count; strColumns = new string[columnNum]; for (int i = 0; i < dt.Columns.Count; i++) { strColumns[i] = dt.Columns[i].ColumnName; } } return strColumns; } #endregion private static DateTime LastDayOfMonth(DateTime datetime) { return datetime.AddDays(1 - datetime.Day).AddMonths(1).AddDays(-1); } public PdfPTable GenerateHeaderzd(string str) { BaseFont baseFont = BaseFontForHeaderFooter; iTextSharp.text.Font font_header2 = new iTextSharp.text.Font(baseFont, 12, iTextSharp.text.Font.NORMAL); float[] widths = new float[] { 480, 100 }; PdfPTable header = new PdfPTable(widths); PdfPCell cell = new PdfPCell(); cell = GenerateOnlyBottomBorderCell(0, iTextSharp.text.Element.ALIGN_LEFT); cell.Phrase = new Paragraph("", font_header2); header.AddCell(cell); cell = GenerateOnlyBottomBorderCell(0, iTextSharp.text.Element.ALIGN_LEFT); cell.Phrase = new Paragraph(str, font_header2); header.AddCell(cell); return header; } } }
有个插入图片的,,有点难缠,特恶心,没完明白
PDFReport 中 public static byte[] ExportPDF(DataTable dt,string Hospital,DateTime ttt,decimal totalAmount) 这里面的参数我以前用的
调用 ,我之前是直接让打开文件了。。。。或者将这个二进制流保存成文件
private FileStreamResult PDFResult(DataTable data, string fileName,decimal totalAmount, string hospital, DateTime ttt) { byte[] buff = PDFReport.ExportPDF(data, hospital, ttt, totalAmount); Stream stream = new MemoryStream(buff); Response.AddHeader("content-disposition", "attachment; filename=" + fileName); return new FileStreamResult(stream, "application/pdf"); }
二进制流转文件 https://www.cnblogs.com/ouyangqiao/p/5643335.html
/// <summary> /// 工具类:文件与二进制流间的转换 /// </summary> public class FileBinaryConvertHelper { /// <summary> /// 将文件转换为byte数组 /// </summary> /// <param name="path">文件地址</param> /// <returns>转换后的byte数组</returns> public static byte[] File2Bytes(string path) { if (!System.IO.File.Exists(path)) { return new byte[0]; } FileInfo fi = new FileInfo(path); byte[] buff = new byte[fi.Length]; FileStream fs = fi.OpenRead(); fs.Read(buff, 0, Convert.ToInt32(fs.Length)); fs.Close(); return buff; } /// <summary> /// 将byte数组转换为文件并保存到指定地址 /// </summary> /// <param name="buff">byte数组</param> /// <param name="savepath">保存地址</param> public static void Bytes2File(byte[] buff, string savepath) { if (System.IO.File.Exists(savepath)) { System.IO.File.Delete(savepath); } FileStream fs = new FileStream(savepath, FileMode.CreateNew); BinaryWriter bw = new BinaryWriter(fs); bw.Write(buff, 0, buff.Length); bw.Close(); fs.Close(); } }

另外加上list<> 转datatable
private DataTable ToDataTable<T>(List<T> items) { var tb = new DataTable(typeof(T).Name); PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (PropertyInfo prop in props) { Type t = GetCoreType(prop.PropertyType); tb.Columns.Add(prop.Name, t); } foreach (T item in items) { var values = new object[props.Length]; for (int i = 0; i < props.Length; i++) { values[i] = props[i].GetValue(item, null); } tb.Rows.Add(values); } return tb; } public static bool IsNullable(Type t) { return !t.IsValueType || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)); } public static Type GetCoreType(Type t) { if (t != null && IsNullable(t)) { if (!t.IsValueType) { return t; } else { return Nullable.GetUnderlyingType(t); } } else { return t; } }
本人小菜鸟,文章若有不当,敬请谅解,如果有可能,请指点我

浙公网安备 33010602011771号