iTextSharp-PDF批量導出

HTML轉PDF批量導出速度太慢且使用Spire.pdf.dll限制頁簽10后需要開通會員才能使用-做出優化

環境:U9 - UI插件?

需求:選擇需要導出的客戶查詢對應對賬數據批量導出PDF并彈出下載框保存到默認位置

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.UI;
using System.Web.UI.WebControls;
using UFIDA.U9.AP.Payment;
using UFIDA.U9.Cust.HuaRui.QueryCustomerUIModel;
using UFIDA.U9.FI.AP.Payment.PayBillUIModel;
using UFIDA.U9.UI.PDHelper;
using UFSoft.UBF.AopFrame.Lock;
using UFSoft.UBF.Business;
using UFSoft.UBF.UI;
using UFSoft.UBF.UI.ControlModel;
using UFSoft.UBF.UI.WebControlAdapter;
using UFSoft.UBF.Util.DataAccess;
using static UFIDA.U9.Cust.HuaRui.HuaRExtendUIPlug.TemplateClass;namespace UFIDA.U9.Cust.HuaRui.HuaRExtendUIPlug
{public partial class QueryCustomerUIFormWebPart : UFSoft.UBF.UI.Custom.ExtendedPartBase{private UFIDA.U9.Cust.HuaRui.QueryCustomerUIModel.QueryCustomerUIFormWebPart _part;IUFButton BtnFresh;public override void AfterInit(UFSoft.UBF.UI.IView.IPart Part, EventArgs args){_part = Part as UFIDA.U9.Cust.HuaRui.QueryCustomerUIModel.QueryCustomerUIFormWebPart;if (_part == null)return;#region 添加按鈕IUFButton BtnTransfer = new UFWebButtonAdapter();BtnTransfer.Text = "批量導出";BtnTransfer.AutoPostBack = true;BtnTransfer.ID = "BtnTransfer";BtnTransfer.Width = 100;BtnTransfer.Height = 20;IUFCard card = (IUFCard)_part.GetUFControlByName(_part.TopLevelContainer, "Card0");card.Controls.Add(BtnTransfer);CommonFunction.Layout(card, BtnTransfer, 0, 0);BtnTransfer.Click += new EventHandler(BtnTransfer_Click);#endregionbase.AfterInit(Part, args);}private void BtnTransfer_Click(object sender, EventArgs e){try{_part.OnDataCollect(this);_part.IsDataBinding = true;_part.IsConsuming = true;_part.Model.ClearErrorMessage();if (_part.Model.QueryCustomerLine.SelectRecords.Count == 0){_part.Model.ErrorMessage.Message = "請選擇數據!";return;}#region 生成HTML文件轉PDF復制到指定文件夾string filePathUrl = "";//文件地址var basePath = AppDomain.CurrentDomain.BaseDirectory;string destinationPath = basePath + @"\FileZipTemp\";string destinationPathZip = basePath + @"\FileZip\";string FileName = "貨款對賬單-" + DateTime.Now.ToString("yyyyMMdd") + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString();if (!Directory.Exists(destinationPath)){Directory.CreateDirectory(destinationPath);}if (!Directory.Exists(destinationPathZip)){Directory.CreateDirectory(destinationPathZip);}string CustomersName = string.Empty;string str = string.Empty;if (_part.Model.QueryCustomerLine.SelectRecords.Count > 1){foreach (QueryCustomerLineRecord rd in _part.Model.QueryCustomerLine.SelectRecords){str += ",N'" + rd.CustomerName + "'";}str = str.Substring(1);CustomersName = "(CustomersName in (" + str + "))";}else{foreach (QueryCustomerLineRecord rd in _part.Model.QueryCustomerLine.SelectRecords){CustomersName = "(CustomersName = N'" + rd.CustomerName + "')";}}DataSet ds = new DataSet();string procBomName = "Cust_HuaRui_ProvideAccountNew";DataParamList lstBom = new DataParamList();lstBom.Add(DataParamFactory.CreateInput("CustomersName", CustomersName));lstBom.Add(DataParamFactory.CreateInput("ContarctsState", null));lstBom.Add(DataParamFactory.CreateInput("UserID", PDContext.Current.UserCode));lstBom.Add(DataParamFactory.CreateInput("SOBAccountingPeriod", null));DataAccessor.RunSP(procBomName, lstBom, out ds);List<ProvideAccount> ProvideAccount = CommonHelper.DataTable2List<ProvideAccount>(ds.Tables[0]);if (ds.Tables[0].Rows.Count == 0){_part.Model.ErrorMessage.Message = "所選客戶沒有貨款對賬相關內容!";return;}var Customers = ProvideAccount.GroupBy(x => x.CustomersName).Select(x => x.Key).ToList();//調用模版提供的默認實現.--默認實現可能會調用相應的Action.foreach (var customer in Customers){var list = ProvideAccount.Where(x => x.CustomersName == customer).ToList();if (list.Count == 0){continue;}//StringBuilder htmlContent = HtmlTOPdf(list, customer);//string htmlFilePathUrl = destinationPathZip + "\\" + FileName;//if (!Directory.Exists(htmlFilePathUrl))//{//    Directory.CreateDirectory(htmlFilePathUrl);//}string pdfFilePathUrl = destinationPath + "\\" + FileName;if (!Directory.Exists(pdfFilePathUrl)){Directory.CreateDirectory(pdfFilePathUrl);}//指定輸出文件路徑//string htmlName = customer + DateTime.Now.ToString("yyyyMMdd") + ".html";string pdfName = customer + DateTime.Now.ToString("yyyyMMdd") + ".pdf";//string htmlPath = Path.Combine(htmlFilePathUrl, htmlName);string pdfPath = Path.Combine(pdfFilePathUrl, pdfName);將HTML內容寫入文件//File.WriteAllText(htmlPath, htmlContent.ToString());從.html文件中獲取HTML字符串//string htmlString = File.ReadAllText(htmlPath);指定插件路徑//string pluginPath = "D:\\yonyou\\U9V60\\Portal\\plugins";設置插件//HtmlConverter.PluginPath = pluginPath;將HTML字符串轉換為PDF//HtmlConverter.Convert(htmlString, pdfPath, true, 100000, new Size(803, 1188), new PdfMargins(0), Spire.Pdf.HtmlConverter.LoadHtmlType.SourceCode);PdfHelper.CreatePDF(pdfPath, list, customer);}#endregion 服務端生成ZIP文件并下載#region 服務端生成ZIP文件并下載string tempZipFilePath = Path.GetTempFileName();string tempZipFilePath1 = "";string tempZipFilePathZip = "";string script = "";try{if (!Directory.Exists(destinationPathZip)){Directory.CreateDirectory(destinationPathZip);}var safePath = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), destinationPath));if (!Directory.Exists(safePath)){Directory.CreateDirectory(safePath);}// 創建臨時ZIP文件//string guid = Guid.NewGuid().ToString();tempZipFilePath1 = Path.Combine(Path.GetTempPath(), FileName + ".zip");System.IO.Compression.ZipFile.CreateFromDirectory(safePath, tempZipFilePath1);File.Copy(tempZipFilePath1, Path.Combine(destinationPathZip, FileName + ".zip"), true);//拼接鏈接script = @"../\FileZip/" + FileName + @"" + ".zip";//延遲刪除文件名稱tempZipFilePathZip = destinationPathZip + FileName + @"" + ".zip";script = string.Format("window.open('{0}'); ", script);AtlasHelper.RegisterAtlasStartupScript((Control)_part.TopLevelContainer, _part.GetType(), "downbload", script, true);}finally{// 清理臨時文件File.Delete(tempZipFilePath);File.Delete(tempZipFilePath1);}#endregion 服務端生成ZIP文件并下載#region 刪除服務端生成的臨時文件夾string folderPath = destinationPath; // 替換為你想要刪除的文件夾路徑try{// 遞歸刪除文件夾及其所有內容Directory.Delete(folderPath, true);var timer = new System.Timers.Timer();timer.Interval = 15000;timer.Elapsed += (sender1, e1) =>{if (!string.IsNullOrEmpty(destinationPathZip))DeleteDirectoryContents(destinationPathZip);timer.Stop();}; timer.Start();//Directory.Delete(destinationPathZip, true);}catch (Exception ex){// 處理任何可能的異常,例如權限問題、路徑不存在等//Console.WriteLine("刪除文件夾時發生錯誤: " + ex.Message);_part.Model.ErrorMessage.Message = "刪除文件夾時發生錯誤!";return;}#endregion 刪除服務端生成的臨時文件夾}catch (Exception ex){_part.Model.ErrorMessage.Message = ex.Message;return;}}public static void DeleteDirectoryContents(string path){foreach (string item in Directory.GetFileSystemEntries(path)){if (File.GetAttributes(item).HasFlag(FileAttributes.Directory)){// 遞歸刪除子目錄DeleteDirectoryContents(item);}else{// 刪除文件File.Delete(item);}}// 刪除空文件夾//Directory.Delete(path);}}
}

需要的幫助類:

1、生成PDF
using iTextSharp.text.pdf.draw;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System;
using System.IO;
using System.Data;
using UFIDA.U9.Cust.HuaRui.HuaRExtendUI;
using System.Collections.Generic;
using System.Linq;namespace UFIDA.U9.Cust.HuaRui.HuaRExtendUIPlug
{public class PdfHelper{private static void SetImg(PdfWriter writer, string path, float fitWidth, float fitHeight, float absoluteX, float absoluteY){try{Image image = Image.GetInstance(path);image.Alignment = Element.ALIGN_MIDDLE;image.ScaleToFit(fitWidth, fitHeight);image.SetAbsolutePosition(absoluteX, absoluteY);writer.DirectContent.AddImage(image);}catch (Exception e){Console.WriteLine(e.Message);throw e;}}public static void CreatePDF(string fileName, List<ProvideAccount> list, string CustomerName){try{Document document = new Document(new Rectangle(803, 1188), 30F, 30F, 100F, 100F);//fileName = Path.GetFullPath("../..") + @"\PdfFiles\" + fileName + ".pdf";PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(fileName, FileMode.Create));// 定義頁眉和頁腳頁碼事件PDFBuilder builder = new PDFBuilder();builder.CustomerName = CustomerName;//設置頁面監聽事件writer.PageEvent = builder;document.Open();//換行Paragraph newLine = new Paragraph("\n");float tableWidthPercentage = 100f; //表格的整體寬度//表格背景色BaseColor green = new BaseColor(175, 215, 136);BaseColor blue = new BaseColor(148, 170, 214);//所需字體string fontPath = Path.GetFullPath("../..") + @"\fonts\";string timesPath = fontPath + "TIMES.TTF";string timesBdPath = fontPath + "TIMESBD.TTF";BaseFont bf = BaseFont.CreateFont(timesPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);BaseFont blodbf = BaseFont.CreateFont(timesBdPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);Font coverFont = new Font(blodbf, 30, Font.NORMAL);Font titleFont = new Font(blodbf, 16, Font.NORMAL);Font coverTiletFontMarked = new Font(blodbf, 16f, Font.NORMAL, new BaseColor(148, 170, 214));Font textFontBold = new Font(blodbf, 10.5f, Font.NORMAL);Font textFont = new Font(bf, 10.5f, Font.NORMAL);Font textFontGray = new Font(blodbf, 10.5f, Font.NORMAL, new BaseColor(215, 215, 215));Font chapterFont = new Font(blodbf, 14f, Font.NORMAL);//設置字體,支持中文BaseFont bfChinese = BaseFont.CreateFont("C:\\WINDOWS\\Fonts\\msyh.ttc,1", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);iTextSharp.text.Font fontChinese = new iTextSharp.text.Font(bfChinese, 7, iTextSharp.text.Font.NORMAL, new BaseColor(0, 0, 0));//獲取datatable數據DataTable Data = GetDataTableList(list);PdfPTable dataTb = new PdfPTable(Data.Columns.Count);dataTb.SetWidths(new float[] { 0.04f, 0.06f, 0.06f, 0.06f, 0.08f, 0.06f, 0.06f, 0.06f, 0.06f, 0.06f, 0.06f, 0.08f, 0.06f, 0.06f, 0.06f, 0.06f, 0.06f, 0.06f, 0.06f });// 每個單元格占多寬dataTb.WidthPercentage = tableWidthPercentage;dataTb.DefaultCell.BorderColor = BaseColor.LIGHT_GRAY;dataTb.DefaultCell.Padding = 1;dataTb.DefaultCell.BorderWidth = 1;dataTb.DefaultCell.HorizontalAlignment = Element.ALIGN_CENTER; // 設置單元格內容水平居中dataTb.DefaultCell.VerticalAlignment = Element.ALIGN_MIDDLE; // 設置單元格內容垂直居中//將datatable表頭轉換成PDFTable的表頭foreach (DataColumn dc in Data.Columns){dataTb.AddCell(new Phrase(dc.ColumnName.ToString(), fontChinese));}//插入數據for (int i = 0; i < Data.Rows.Count; i++){for (int j = 0; j < Data.Columns.Count; j++){dataTb.AddCell(new Phrase(Data.Rows[i][j].ToString(), fontChinese));}}document.Add(dataTb);document.Add(newLine);document.Close();}catch (Exception ex){throw new Exception("PDF生成失敗-錯誤信息:" + ex.Message);}}/// <summary>/// 創建默認dataTable數據/// </summary>/// <returns></returns>public static DataTable GetDataTableList(List<ProvideAccount> list){DataTable dt = new DataTable();dt.Columns.Add("序號", typeof(string));//添加列  dt.Columns.Add("合同日期", typeof(string));//添加列 dt.Columns.Add("合同編碼", typeof(string));//添加列 dt.Columns.Add("客戶PO號", typeof(string));//添加列 dt.Columns.Add("項目名稱", typeof(string));//添加列 dt.Columns.Add("最終合同金額", typeof(string));//添加列 dt.Columns.Add("出庫金額", typeof(string));//添加列 dt.Columns.Add("已開票金額", typeof(string));//添加列 dt.Columns.Add("已付款金額", typeof(string));//添加列 dt.Columns.Add("應收金額", typeof(string));//添加列 dt.Columns.Add("逾期金額", typeof(string));//添加列 dt.Columns.Add("付款方式", typeof(string));//添加列 dt.Columns.Add("到期時間", typeof(string));//添加列 dt.Columns.Add("發貨完成", typeof(string));//添加列 dt.Columns.Add("合同狀態", typeof(string));//添加列 dt.Columns.Add("業務員", typeof(string));//添加列 dt.Columns.Add("業務單元", typeof(string));//添加列 dt.Columns.Add("歷史合同編號", typeof(string));//添加列 dt.Columns.Add("初始合同金額", typeof(string));//添加列 //循環添加行的數據int num = 1;foreach (var item in list){DataRow dtRow = dt.NewRow();dtRow["序號"] = num;dtRow["合同日期"] = item.CreatedOn;dtRow["合同編碼"] = item.HisCRMDocNo;dtRow["客戶PO號"] = item.CustomerPO;dtRow["項目名稱"] = item.ProjectName;dtRow["最終合同金額"] = item.ContractAmount;dtRow["出庫金額"] = item.ShipSumMoney;dtRow["已開票金額"] = item.InvoicedAmount;dtRow["已付款金額"] = item.BalanceAmount;dtRow["應收金額"] = item.BusinessReceivaBalance;dtRow["逾期金額"] = item.AnticipatoryRight;dtRow["付款方式"] = item.ConfirmTermName;dtRow["到期時間"] = item.EstimatedPayDate;dtRow["發貨完成"] = item.IsCompletedShip;dtRow["合同狀態"] = item.contarctsState;dtRow["業務員"] = item.OperatorsName;dtRow["業務單元"] = item.BusinessUnit;dtRow["歷史合同編號"] = item.CRMDocNo;dtRow["初始合同金額"] = item.OriginalContractAmount;dt.Rows.Add(dtRow);num++;}//添加合計行DataRow dtRow2 = dt.NewRow();dtRow2["序號"] = "";dtRow2["合同日期"] = "";dtRow2["合同編碼"] = "";dtRow2["客戶PO號"] = "";dtRow2["項目名稱"] = "合計";dtRow2["最終合同金額"] = list.Sum(x => x.ContractAmount);dtRow2["出庫金額"] = list.Sum(x => x.ShipSumMoney);dtRow2["已開票金額"] = list.Sum(x => x.InvoicedAmount);dtRow2["已付款金額"] = list.Sum(x => x.BalanceAmount);dtRow2["應收金額"] = list.Sum(x => x.BusinessReceivaBalance);dtRow2["逾期金額"] = list.Sum(x => x.AnticipatoryRight);dtRow2["付款方式"] = "";dtRow2["到期時間"] = "";dtRow2["發貨完成"] = "";dtRow2["合同狀態"] = "";dtRow2["業務員"] = "";dtRow2["業務單元"] = "";dtRow2["歷史合同編號"] = "";dtRow2["初始合同金額"] = list.Sum(x => x.OriginalContractAmount);dt.Rows.Add(dtRow2);return dt;}private static PdfPCell GetCell(Phrase phrase, BaseColor color, int colSpan, int rowSpan){PdfPCell cells = new PdfPCell(phrase);cells.UseAscender = true;cells.MinimumHeight = 20f;cells.HorizontalAlignment = Element.ALIGN_CENTER;cells.VerticalAlignment = 5;cells.Colspan = colSpan;cells.Rowspan = rowSpan;cells.NoWrap = false;if (color != null){cells.BackgroundColor = color;}return cells;}}
}
2、設置頁眉和頁腳
using System;
using System.IO;
using iTextSharp.text.pdf;
using iTextSharp.text;namespace UFIDA.U9.Cust.HuaRui.HuaRExtendUIPlug
{public class PDFBuilder : PdfPageEventHelper{public string CustomerName;// 模板public PdfTemplate total;// 基礎字體對象public BaseFont bf = null;// 利用基礎字體生成的字體對象,一般用于生成中文文字public Font fontDetail = null;/// <summary>/// 文檔打開時創建模板/// </summary>/// <param name="writer"></param>/// <param name="document"></param>public override void OnOpenDocument(PdfWriter writer, Document document){total = writer.DirectContent.CreateTemplate(50, 50);// 共 頁 的矩形的長寬高}/// <summary>/// 關閉每頁的時候,寫入頁眉,頁腳。/// </summary>/// <param name="writer"></param>/// <param name="document"></param>public override void OnEndPage(PdfWriter writer, Document document){this.AddPage(writer, document);}public static void SetImg(PdfWriter writer, string path, float fitWidth, float fitHeight, float absoluteX, float absoluteY){try{Image image = Image.GetInstance(path);image.Alignment = Element.ALIGN_MIDDLE;image.ScaleToFit(fitWidth, fitHeight);image.SetAbsolutePosition(absoluteX, absoluteY);writer.DirectContent.AddImage(image);}catch (Exception e){Console.WriteLine(e.Message);throw e;}}/// <summary>/// 加分頁/// </summary>/// <param name="writer"></param>/// <param name="document"></param>public void AddPage(PdfWriter writer, Document document){if (document.PageNumber >=1){string fontPath = Path.GetFullPath("../..") + @"\fonts\";try{string timesPath = fontPath + "TIMES.TTF";bf = BaseFont.CreateFont(timesPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);}catch (Exception e){Console.WriteLine(e.Message);throw e;}BaseFont blodf = null;try{string timesBdPath = fontPath + "TIMESBD.TTF";blodf = BaseFont.CreateFont(timesBdPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);}catch (Exception e){Console.WriteLine(e.Message);throw e;}//設置字體,支持中文BaseFont bfChinese = BaseFont.CreateFont("C:\\WINDOWS\\Fonts\\msyh.ttc,1", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);iTextSharp.text.Font fontChinese = new iTextSharp.text.Font(bfChinese, 16, iTextSharp.text.Font.BOLD, new BaseColor(0, 0, 0));iTextSharp.text.Font fontChinese1 = new iTextSharp.text.Font(bfChinese, 7, iTextSharp.text.Font.NORMAL, new BaseColor(0, 0, 0));//Phrase pageNumberPh = new Phrase("page " + (document.PageNumber - 1), fontChinese);float center = document.PageSize.Right / 2;//頁面的水平中點float headerleft = document.PageSize.GetLeft(50);//頁面的z左邊距float right = document.PageSize.GetRight(90);//頁面的z左邊距float top = document.PageSize.Top - 36;float bottom = document.PageSize.Bottom + 10;float x = document.PageSize.Width / 3;float y = document.PageSize.Top - 30;Phrase header = new Paragraph("浙江華睿科技股份有限公司貨款對賬表", fontChinese);Paragraph header1 = new Paragraph("致:" + CustomerName, fontChinese1);Paragraph header2 = new Paragraph("現將浙江華睿科技股份有限公司與貴單位的經濟業務往來情況知會貴單位,請核對并按照協議約定時間支付貨款,到期貨款請盡快支付", fontChinese1);Paragraph header3 = new Paragraph("貴公司往來貨款情況明細如下:(單位:元 對賬截止:", fontChinese1);Paragraph header4 = new Paragraph(DateTime.Now.ToString("yyyy-MM-dd"), fontChinese1);ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_LEFT, header, x, y, 0); //頁眉標題ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_LEFT, header1, headerleft, y - 20, 0); //頁眉內容ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_LEFT, header2, headerleft, y - 35, 0); //頁眉ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_LEFT, header3, headerleft, y - 50, 0); //頁眉ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_RIGHT, header4, right + 20, y - 50, 0); //頁眉//ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_CENTER, pageNumberPh, center, bottom - 20, 0); //頁碼Phrase pageNumberPh = new Phrase("說明:多頁賬單請蓋騎縫章,謝謝配合", fontChinese1);Paragraph header11 = new Paragraph("浙江華睿科技股份有限公司(蓋章)", fontChinese1);Paragraph header12 = new Paragraph("(蓋章)", fontChinese1);Paragraph header13 = new Paragraph(CustomerName, fontChinese1);Paragraph header21 = new Paragraph("日期:", fontChinese1);Paragraph header22 = new Paragraph("日期:", fontChinese1);Paragraph header31 = new Paragraph("對賬人(簽字):", fontChinese1);Paragraph header32 = new Paragraph("對賬人(簽字):", fontChinese1);Paragraph header41 = new Paragraph("不符原因:", fontChinese1);ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_CENTER, pageNumberPh, center, bottom + 70, 0); //頁腳ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_LEFT, header11, headerleft, bottom + 45, 0); //頁腳內容ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_LEFT, header12, x + 120, bottom + 45, 0); //頁腳內容ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_LEFT, header13, right - 60, bottom + 45, 0); //頁腳內容ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_LEFT, header21, headerleft, bottom + 30, 0); //頁腳內容ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_LEFT, header22, x + 120, bottom + 30, 0); //頁腳內容ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_LEFT, header31, headerleft, bottom + 15, 0); //頁腳內容ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_LEFT, header32, x + 120, bottom + 15, 0); //頁腳內容ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_LEFT, header41, x + 120, bottom, 0); //頁腳內容}}/// <summary>/// 關閉文檔時,替換模板,完成整個頁眉頁腳組件/// </summary>/// <param name="writer"></param>/// <param name="document"></param>public override void OnCloseDocument(PdfWriter writer, Document document){// 關閉文檔的時候,將模板替換成實際的 Y 值,至此,page x of y 制作完畢,完美兼容各種文檔size。total.BeginText();total.SetFontAndSize(bf, 9);// 生成的模版的字體、顏色string foot2 = " " + (writer.PageNumber) + " 頁"; //頁腳內容拼接  如  第1頁/共2頁total.ShowText(foot2);// 模版顯示的內容total.EndText();total.ClosePath();}}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/72146.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/72146.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/72146.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【RabbitMQ】Spring Boot 結合 RabbitMQ 完成應用間的通信

&#x1f525;個人主頁&#xff1a; 中草藥 &#x1f525;專欄&#xff1a;【中間件】企業級中間件剖析 Spring 框架與 RabbitMQ 的整合主要通過 Spring AMQP&#xff08;Advanced Message Queuing Protocol&#xff09;模塊實現&#xff0c;提供了便捷的消息隊列開發能力。 引…

CDefView::_GetPIDL函數分析之ListView_GetItem函數的參數item的item.mask 為LVIF_PARAM

CDefView::_GetPIDL函數分析之ListView_GetItem函數的參數item的item.mask 為LVIF_PARAM 第一部分&#xff1a; 1: kd> t SHELL32!CDefView::_GetPIDL: 001b:77308013 55 push ebp 1: kd> dv this 0x00000015 i 0n21 …

MongoDB分頁實現方式對比:PageRequest vs Skip/Limit

MongoDB分頁實現方式對比&#xff1a;PageRequest vs Skip/Limit 一、基本概念1.1 PageRequest分頁1.2 Skip/Limit分頁 二、主要區別2.1 使用方式2.2 參數計算2.3 適用場景PageRequest適用場景&#xff1a;Skip/Limit適用場景&#xff1a; 三、性能考慮3.1 PageRequest的性能特…

Manus(一種AI代理或自動化工具)與DeepSeek(一種強大的語言模型或AI能力)結合使用任務自動化和智能決策

一、Manus與DeepSeek差異 十分好奇DeepSeek和Manus究竟誰更厲害些&#xff0c;DeepSeek是知識型大腦&#xff0c;Manus則是全能型執行者。即DeepSeek專注于語言處理、知識整合與專業文本生成。其核心優勢在于海量參數支持的深度學習和知識推理能力&#xff0c;例如撰寫論文、潤…

UI自動化:poium測試庫

以下是關于 poium 測試庫 的詳細介紹&#xff0c;涵蓋其核心功能、使用方法及與原生 Selenium 的對比&#xff0c;幫助快速掌握這一工具&#xff1a; 1. poium 簡介 定位&#xff1a;基于 Selenium 的 Page Object 模式增強庫&#xff0c;專注于簡化元素定位和頁面操作。 核心…

C#結構體(Struct)詳解

在 C# 中&#xff0c;?結構體&#xff08;struct&#xff09;? 是一種值類型數據類型&#xff0c;適用于封裝小型數據組。與類&#xff08;class&#xff09;不同&#xff0c;結構體在棧&#xff08;Stack&#xff09;上分配內存&#xff0c;且賦值時會發生值復制。以下是結構…

UVC攝像頭命令推流,推到rv1126里面去

ffmpeg命令查詢UVC設備 .\ffmpeg.exe -list_devices true -f dshow -i dummy 上圖是查詢UVC設備的效果圖&#xff0c;畫紅框的部分是UVC設備的設備名稱"USB2.0 PC CAMERA"和設備號 "device_pnp_\\?\usb#vid_1908&pid_2310&mi_00#8&39abfe5&0&a…

Linux中的基本指令(上)

目錄 ls指令 判斷linux中文件 pwd指令 認識路徑 ?編輯 絕對路徑/相對路徑 cd指令 簡要理解用戶 理解家目錄 echo指令和printf指令 touch指令 mkdir指令 cat指令 tree指令 rmdir指令和rm指令 man指令 cp指令 which指令 alias 指令 date指令 cal指令 理解…

多數元素——面試經典150題(力扣)

題目 給定一個大小為 n 的數組 nums &#xff0c;返回其中的多數元素。多數元素是指在數組中出現次數 大于 ? n/2 ? 的元素。 你可以假設數組是非空的&#xff0c;并且給定的數組總是存在多數元素。 示例 1&#xff1a; 輸入&#xff1a;nums [3,2,3] 輸出&#xff1a;3 …

Qt 數據庫操作(Sqlite)

數據庫簡介 關于數據庫的基礎知識這里就不做介紹了&#xff0c;相關博客可以查看&#xff1a; SQL基礎知識 數據庫學霸筆記 上面博客都寫的比較詳細&#xff0c;本文主要介紹如何使用Qt進行數據庫相關操作&#xff0c;數據庫分為關系型數據庫和非關系型數據&#xff0c;關系…

網絡安全 api 網絡安全 ast技術

隨著應用或者API被攻擊利用已經越來越多&#xff0c;雖然來自開源組件的漏洞加劇了這一現象的發生&#xff0c;但是&#xff0c;其實主要還是在于應用程序或者API本身沒有做好防范&#xff0c;根源在于源代碼本身的質量沒有嚴格把控。AST是指Application Security Testing&…

Mac 配置 Maven JDK

不使用 Homebrew&#xff0c;創建指定版本 JDK 1、官網下載指定版本并安裝……省略 2、vi &#xff5e;/.zshrc 同時要檢查 bash_profile 是否存在。 if [ -f ~/.bash_profile ] ; thensource ~/.bash_profile fiJAVA_HOME_11/Library/Java/JavaVirtualMachines/jdk-11.0.1…

【每日學點HarmonyOS Next知識】拖拽調整列表順序、tab回彈、自定義彈窗this、狀態變量修飾枚舉

1、HarmonyOS 功能實現&#xff08;拖拽調整列表順序&#xff09;&#xff1f; 可參考&#xff1a; import curves from ohos.curves; import Curves from ohos.curvesEntry Component struct ListItemExample {State private arr: number[] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]…

Django部署Filemanagement

Pycharm搭建項目安裝虛擬環境 mysqlclient對mysql的安裝&#xff0c;配置有要求 pymsql偽裝成mysqlclient&#xff0c;pymysql可以操縱mysql pip install pymysql操作sql5.7 mysql8.0會出現與pycharm不兼容問題&#xff0c;會報錯&#xff0c;所以降到5.7 # 進入mysql 需要…

【病毒分析】熊貓燒香病毒分析及其查殺修復

目錄 前言 一、樣本概況 1.1 樣本信息 1.2 測試環境及工具 1.3 分析目標 二、具體行為分析 2.1 主要行為 2.1.1 惡意程序對用戶造成的危害 2.2 惡意代碼分析 2.2.1 加固后的惡意代碼樹結構圖(是否有加固) 2.2.2 惡意程序的代碼分析片段 三、解決方案(或總結) 3.1 …

Spring Boot集成Spring Statemachine

Spring Statemachine 是 Spring 框架下的一個模塊&#xff0c;用于簡化狀態機的創建和管理&#xff0c;它允許開發者使用 Spring 的特性&#xff08;如依賴注入、AOP 等&#xff09;來構建復雜的狀態機應用。以下是關于 Spring Statemachine 的詳細介紹&#xff1a; 主要特性 …

數組總和 (leetcode 40

leetcode系列 文章目錄 一、核心操作二、外層配合操作三、核心模式代碼總結 去重方式和之前三數之和一樣&#xff0c;也可以用used數組去重&#xff0c;但本次嘗試使用set去重 一、核心操作 如果count為0了&#xff0c;則證明正好減到了0&#xff0c;就可以收獲&#xff0c;…

sqli-lab靶場學習(八)——Less26-28

前言 25關已經出現了初步的一些關鍵字過濾&#xff0c;通過雙寫可以繞過。后面的關卡&#xff0c;我們會遇到更多關鍵字過濾&#xff0c;需要各種技巧繞過。 Less26 第26關寫了會過濾空格和注釋符。有很多的答案&#xff0c;會用%a0替代空格&#xff0c;但據說這是sqli-labs部…

python:VOC格式數據集轉換為YOLO數據集格式

作者&#xff1a;CSDN _養樂多_ 本文將介紹如何將目標檢測中常用的VOC格式數據集轉換為YOLO數據集&#xff0c;并進行數據集比例劃分&#xff0c;從而方便的進行YOLO目標檢測。 如果不想分兩步&#xff0c;可以直接看第三節代碼。 文章目錄 一、將VOC格式數據集轉換為YOLO格…

Docker容器安裝軟件(完整版)

文章目錄 一、安裝Docker1.1 docker 相關的命令1.2 配置鏡像加速 二. 安裝es2.1 創建網絡2.2 拉取鏡像2.3 創建掛載點目錄2.4 部署單點es&#xff0c;創建es容器2.5 編寫elasticsearch.yml2.6 重啟es容器2.7 測試Elasticsearch是否安裝成功 三. 基于Docker安裝Kibana3.1 拉取鏡…