年末將至,又到了一年一度的收集發票時間,平時零零碎碎的花錢都是不在意開發票,現在好了,到處找發票來報銷,簡直頭大,
東拼西湊,終於搞定了全部發票,大伙多余的發票,麻煩艾特我一下啊,不限日期,能開發票的都可以,謝謝啦。文章后有彩蛋~
這么多的發票,一張一張打印,要浪費我多少時間,就想着合並這些PDF文件(發票)一起打印,節省時間。
還尋思這網上找一個軟件來使使,都很(méi)委(līang)婉(xīn)的想收費,在線轉PDF的還給我打水印,恰巧今天公司網速不行。
來吧,自己搞!程序猿沒有什么不可能!
Spire.PDF
NPOI、DocX、Epplus……這些開源且免費的優秀組件,大家應該是耳熟能詳的,而Spire是一款企業級的收費組件,Spire.PDF for .NET
是一個專業的PDF組件,用於在.NET應用程序中創建,編寫,編輯,處理和閱讀PDF文件,功能十分豐富…………
提取關鍵詞:收費、穩定、高效
具體我不再過多的啰嗦了,詳細我推薦看這篇《 高效而穩定的企業級.NET Office 組件Spire(.NET組件介紹之二)》
合並PDF
回到今天的問題,合並發票,合並PDF,然后一次性打印。其實吧,主要代碼就兩行:
1 var doc = PdfDocument.MergeFiles(allFiles.ToArray()); 2 doc.Save(DateTime.Now.ToString("yyyyMMddHHmmss") + ".pdf", FileFormat.PDF);
然后,你們輸出之后會發現,很(méi)漂(līang)亮(xīn)的水印:
“Evaluation Warning:The document was created with Spire.PDF for .NET”
簡直玷污我心愛的發票!!!!
解決
既然隱藏不了,那合並的第一頁加入一個空頁不就行了?!生成PDF后,然后從第二頁開始打印或是刪去第一頁不就行了?!就這么干!
1 var first = new PdfDocument(); 2 first.AppendPage(); //加入一個空頁 3 for (int idx = 0; idx < allFiles.Count; idx++) 4 { 5 var next = new PdfDocument(allFiles[idx]); 6 first.AppendPage(next); 7 } 8 first.SaveToFile(DateTime.Now.ToString("yyyyMMddHHmmss")+".pdf", FileFormat.PDF);
工具很簡單,就不放到Git上去了,源碼:
界面:

namespace 合並PDF { partial class mainForm { /// <summary> /// 必需的設計器變量。 /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 清理所有正在使用的資源。 /// </summary> /// <param name="disposing">如果應釋放托管資源,為 true;否則為 false。</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows 窗體設計器生成的代碼 /// <summary> /// 設計器支持所需的方法 - 不要修改 /// 使用代碼編輯器修改此方法的內容。 /// </summary> private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.btnAdd = new System.Windows.Forms.Button(); this.btnMerge = new System.Windows.Forms.Button(); this.bgw = new System.ComponentModel.BackgroundWorker(); this.listView1 = new System.Windows.Forms.ListView(); this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); this.btnRemove = new System.Windows.Forms.ToolStripMenuItem(); this.statusStrip1 = new System.Windows.Forms.StatusStrip(); this.progressBar = new System.Windows.Forms.ToolStripProgressBar(); this.tipStatu = new System.Windows.Forms.ToolStripStatusLabel(); this.btnSplit = new System.Windows.Forms.Button(); this.contextMenuStrip1.SuspendLayout(); this.statusStrip1.SuspendLayout(); this.SuspendLayout(); // // btnAdd // this.btnAdd.Location = new System.Drawing.Point(409, 12); this.btnAdd.Name = "btnAdd"; this.btnAdd.Size = new System.Drawing.Size(67, 24); this.btnAdd.TabIndex = 2; this.btnAdd.Text = "添加文件"; this.btnAdd.UseVisualStyleBackColor = true; this.btnAdd.Click += new System.EventHandler(this.btnSearch_Click); // // btnMerge // this.btnMerge.Font = new System.Drawing.Font("宋體", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); this.btnMerge.Location = new System.Drawing.Point(409, 43); this.btnMerge.Name = "btnMerge"; this.btnMerge.Size = new System.Drawing.Size(67, 24); this.btnMerge.TabIndex = 3; this.btnMerge.Text = "開始合並"; this.btnMerge.UseVisualStyleBackColor = true; this.btnMerge.Click += new System.EventHandler(this.btnMerge_Click); // // bgw // this.bgw.WorkerReportsProgress = true; this.bgw.DoWork += new System.ComponentModel.DoWorkEventHandler(this.bgw_DoWork); this.bgw.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.bgw_ProgressChanged); this.bgw.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.bgw_RunWorkerCompleted); // // listView1 // this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.columnHeader1}); this.listView1.ContextMenuStrip = this.contextMenuStrip1; this.listView1.FullRowSelect = true; this.listView1.GridLines = true; this.listView1.Location = new System.Drawing.Point(12, 12); this.listView1.MultiSelect = false; this.listView1.Name = "listView1"; this.listView1.Size = new System.Drawing.Size(391, 190); this.listView1.TabIndex = 4; this.listView1.UseCompatibleStateImageBehavior = false; this.listView1.View = System.Windows.Forms.View.Details; // // columnHeader1 // this.columnHeader1.Text = "文件"; this.columnHeader1.Width = 350; // // contextMenuStrip1 // this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.btnRemove}); this.contextMenuStrip1.Name = "contextMenuStrip1"; this.contextMenuStrip1.Size = new System.Drawing.Size(101, 26); // // btnRemove // this.btnRemove.Name = "btnRemove"; this.btnRemove.Size = new System.Drawing.Size(100, 22); this.btnRemove.Text = "移除"; this.btnRemove.Click += new System.EventHandler(this.btnRemove_Click); // // statusStrip1 // this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.progressBar, this.tipStatu}); this.statusStrip1.Location = new System.Drawing.Point(0, 205); this.statusStrip1.Name = "statusStrip1"; this.statusStrip1.Size = new System.Drawing.Size(488, 22); this.statusStrip1.TabIndex = 5; this.statusStrip1.Text = "statusStrip1"; // // progressBar // this.progressBar.Name = "progressBar"; this.progressBar.Size = new System.Drawing.Size(100, 16); // // tipStatu // this.tipStatu.Name = "tipStatu"; this.tipStatu.Size = new System.Drawing.Size(27, 17); this.tipStatu.Text = "0/0"; // // btnSplit // this.btnSplit.Font = new System.Drawing.Font("宋體", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); this.btnSplit.Location = new System.Drawing.Point(409, 73); this.btnSplit.Name = "btnSplit"; this.btnSplit.Size = new System.Drawing.Size(67, 24); this.btnSplit.TabIndex = 6; this.btnSplit.Text = "開始拆分"; this.btnSplit.UseVisualStyleBackColor = true; this.btnSplit.Click += new System.EventHandler(this.btnSplit_Click); // // mainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(488, 227); this.Controls.Add(this.btnSplit); this.Controls.Add(this.statusStrip1); this.Controls.Add(this.listView1); this.Controls.Add(this.btnMerge); this.Controls.Add(this.btnAdd); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MaximumSize = new System.Drawing.Size(504, 266); this.MinimumSize = new System.Drawing.Size(504, 266); this.Name = "mainForm"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "PDF Merge"; this.contextMenuStrip1.ResumeLayout(false); this.statusStrip1.ResumeLayout(false); this.statusStrip1.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Button btnAdd; private System.Windows.Forms.Button btnMerge; private System.ComponentModel.BackgroundWorker bgw; private System.Windows.Forms.ListView listView1; private System.Windows.Forms.ColumnHeader columnHeader1; private System.Windows.Forms.StatusStrip statusStrip1; private System.Windows.Forms.ToolStripProgressBar progressBar; private System.Windows.Forms.ToolStripStatusLabel tipStatu; private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; private System.Windows.Forms.ToolStripMenuItem btnRemove; private System.Windows.Forms.Button btnSplit; } }
后台:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Windows.Forms; using Spire.Pdf; using System.Threading; using Spire.Pdf.Graphics; using System.Drawing; using System.IO; namespace 合並PDF { public partial class mainForm : Form { public mainForm() { InitializeComponent(); } List<string> allFiles = new List<string>(); private void btnSearch_Click(object sender, EventArgs e) { OpenFileDialog openFile = new OpenFileDialog(); openFile.Filter = "PDF文件|*.pdf"; openFile.Multiselect = true; if (openFile.ShowDialog() == DialogResult.OK) { foreach (var fi in openFile.FileNames) { if (allFiles.Contains(fi)) continue; this.listView1.Items.Add(new ListViewItem(fi)); allFiles.Add(fi); } progressBar.Minimum = 0; progressBar.Maximum = allFiles.Count; } } bool bMerge = false; private void btnMerge_Click(object sender, EventArgs e) { if (!bgw.IsBusy) { if (allFiles.Count <= 1) { MessageBox.Show("請至少選擇 2 個PDF文件"); return; } CtrlStatu(false); bMerge = true; bgw.RunWorkerAsync(); } } void Merge() { var first = new PdfDocument(); first.AppendPage(); //加入一個空頁 for (int idx = 0; idx < allFiles.Count; idx++) { var next = new PdfDocument(allFiles[idx]); first.AppendPage(next); ReportInfo(idx + 1, allFiles.Count); Thread.Sleep(100); } first.SaveToFile(DateTime.Now.ToString("yyyyMMddHHmmss") + ".pdf", FileFormat.PDF); } private void CtrlStatu(bool b) { listView1.Enabled = b; btnMerge.Enabled = b; btnAdd.Enabled = b; } private void bgw_DoWork(object sender, DoWorkEventArgs e) { if (bMerge) { Merge(); } if (bSplit) { Split(); } } /// <summary> /// 輸出消息 /// </summary> public void ReportInfo(int idx, int count) { bgw.ReportProgress(1, idx + "/" + count); } private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e) { var userState = e.UserState.ToString(); tipStatu.Text = userState; progressBar.Value = Convert.ToInt32(userState.Split('/')[0]); } private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { tipStatu.Text = "完成..."; CtrlStatu(true); bMerge = bSplit = false; } private void btnRemove_Click(object sender, EventArgs e) { if (this.listView1.SelectedItems.Count > 0) { int idx = this.listView1.SelectedItems[0].Index; allFiles.Remove(this.listView1.SelectedItems[0].Text); this.listView1.Items[idx].Remove(); } } bool bSplit = false; private void btnSplit_Click(object sender, EventArgs e) { if (!bgw.IsBusy) { if (allFiles.Count < 1) { MessageBox.Show("請至少選擇 1 個PDF文件"); return; } CtrlStatu(false); bSplit = true; bgw.RunWorkerAsync(); } } void Split() { var dir = System.Windows.Forms.Application.StartupPath + "\\拆分"; if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } string path = ""; PdfTextLayout format = new PdfTextLayout(); format.Break = PdfLayoutBreakType.FitPage; format.Layout = PdfLayoutType.Paginate; string curTime = DateTime.Now.ToString("yyyyMMddHHmmss"); for (int idx = 0; idx < allFiles.Count; idx++) { PdfDocument pdf = new PdfDocument(); FileInfo file = new FileInfo(allFiles[idx]); string fileName = file.Name.Replace(file.Extension, ""); pdf.LoadFromFile(allFiles[idx]); path = string.Format("{0}\\{1}_",dir, fileName) + "第{0}頁_"+curTime+".pdf"; pdf.Split(path); pdf.Close(); ReportInfo(idx + 1, allFiles.Count); Thread.Sleep(100); } } } }
本文已獨家授權給腳本之家(ID:jb51net)公眾號發布