C#实现PDF合并、裁剪功能

新建终端 ,先下载所需要的包

cs 复制代码
dotnet add package iTextSharp

MainForm

cs 复制代码
using System;
using System.Windows.Forms;

namespace PDFTools
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void btnSplitPdf_Click(object sender, EventArgs e)
        {
            SplitForm splitForm = new SplitForm();
            splitForm.ShowDialog();
        }

        private void btnMergePdf_Click(object sender, EventArgs e)
        {
            MergeForm mergeForm = new MergeForm();
            mergeForm.ShowDialog();
        }

        private void btnAnnotatePdf_Click(object sender, EventArgs e)
        {
            // 使用无参构造函数
            AnnotationForm annotateForm = new AnnotationForm();
            annotateForm.ShowDialog();
        }
    }
}

MainForm.Designer.cs

cs 复制代码
namespace PDFTools
{
    partial class MainForm
    {
        private System.ComponentModel.IContainer components = null;

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码

        private void InitializeComponent()
        {
            this.btnSplitPdf = new System.Windows.Forms.Button();
            this.btnMergePdf = new System.Windows.Forms.Button();
            this.btnAnnotatePdf = new System.Windows.Forms.Button();
            this.SuspendLayout();
            
            // btnSplitPdf
            this.btnSplitPdf.Location = new System.Drawing.Point(50, 30);
            this.btnSplitPdf.Name = "btnSplitPdf";
            this.btnSplitPdf.Size = new System.Drawing.Size(200, 60);
            this.btnSplitPdf.TabIndex = 0;
            this.btnSplitPdf.Text = "PDF切割";
            this.btnSplitPdf.Font = new System.Drawing.Font("微软雅黑", 12F);
            this.btnSplitPdf.Click += new System.EventHandler(this.btnSplitPdf_Click);
            
            // btnMergePdf
            this.btnMergePdf.Location = new System.Drawing.Point(50, 110);
            this.btnMergePdf.Name = "btnMergePdf";
            this.btnMergePdf.Size = new System.Drawing.Size(200, 60);
            this.btnMergePdf.TabIndex = 1;
            this.btnMergePdf.Text = "PDF合并";
            this.btnMergePdf.Font = new System.Drawing.Font("微软雅黑", 12F);
            this.btnMergePdf.Click += new System.EventHandler(this.btnMergePdf_Click);
            
            // btnAnnotatePdf
            this.btnAnnotatePdf.Location = new System.Drawing.Point(50, 190);
            this.btnAnnotatePdf.Name = "btnAnnotatePdf";
            this.btnAnnotatePdf.Size = new System.Drawing.Size(200, 60);
            this.btnAnnotatePdf.TabIndex = 2;
            this.btnAnnotatePdf.Text = "PDF标注";
            this.btnAnnotatePdf.Font = new System.Drawing.Font("微软雅黑", 12F);
            this.btnAnnotatePdf.Click += new System.EventHandler(this.btnAnnotatePdf_Click);
            
            // MainForm
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(300, 280);
            this.Controls.Add(this.btnAnnotatePdf);
            this.Controls.Add(this.btnMergePdf);
            this.Controls.Add(this.btnSplitPdf);
            this.Name = "MainForm";
            this.Text = "PDF工具";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.ResumeLayout(false);
        }

        #endregion

        private System.Windows.Forms.Button btnSplitPdf;
        private System.Windows.Forms.Button btnMergePdf;
        private System.Windows.Forms.Button btnAnnotatePdf;
    }
}

AnnotationForm.cs

cs 复制代码
using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;

namespace PDFTools
{
    public partial class AnnotationForm : Form
    {
        private string pdfFilePath;
        private Bitmap signatureBitmap;
        private System.ComponentModel.IContainer components = null;

        private Label lblFileName;
        private Button btnSelectFile;
        private Label lblPageInfo;
        private NumericUpDown numericPageNumber;
        private Label label1;
        private TextBox txtAnnotationText;
        private Button btnAddText;
        private Button btnLoadSignature;
        private PictureBox pictureBoxSignature;
        private Button btnAddSignature;
        private Button btnCaptureSignature;
        private Button btnSave;

        public AnnotationForm()
        {
            InitializeComponent();
            pdfFilePath = "";
            lblFileName.Text = "未选择文件";
            lblPageInfo.Text = "总页数: 0";
            numericPageNumber.Enabled = false;
        }

        private void InitializeComponent()
        {
            this.lblFileName = new System.Windows.Forms.Label();
            this.btnSelectFile = new System.Windows.Forms.Button();
            this.lblPageInfo = new System.Windows.Forms.Label();
            this.numericPageNumber = new System.Windows.Forms.NumericUpDown();
            this.label1 = new System.Windows.Forms.Label();
            this.txtAnnotationText = new System.Windows.Forms.TextBox();
            this.btnAddText = new System.Windows.Forms.Button();
            this.btnLoadSignature = new System.Windows.Forms.Button();
            this.pictureBoxSignature = new System.Windows.Forms.PictureBox();
            this.btnAddSignature = new System.Windows.Forms.Button();
            this.btnCaptureSignature = new System.Windows.Forms.Button();
            this.btnSave = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this.numericPageNumber)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxSignature)).BeginInit();
            this.SuspendLayout();
            
            // lblFileName
            this.lblFileName.AutoSize = true;
            this.lblFileName.Location = new System.Drawing.Point(120, 25);
            this.lblFileName.Name = "lblFileName";
            this.lblFileName.Size = new System.Drawing.Size(77, 12);
            this.lblFileName.TabIndex = 0;
            this.lblFileName.Text = "未选择文件";
            
            // btnSelectFile
            this.btnSelectFile.Location = new System.Drawing.Point(20, 20);
            this.btnSelectFile.Name = "btnSelectFile";
            this.btnSelectFile.Size = new System.Drawing.Size(90, 25);
            this.btnSelectFile.TabIndex = 1;
            this.btnSelectFile.Text = "选择PDF文件";
            this.btnSelectFile.Click += new System.EventHandler(this.btnSelectFile_Click);
            
            // lblPageInfo
            this.lblPageInfo.AutoSize = true;
            this.lblPageInfo.Location = new System.Drawing.Point(20, 60);
            this.lblPageInfo.Name = "lblPageInfo";
            this.lblPageInfo.Size = new System.Drawing.Size(59, 12);
            this.lblPageInfo.TabIndex = 2;
            this.lblPageInfo.Text = "总页数: 0";
            
            // numericPageNumber
            this.numericPageNumber.Location = new System.Drawing.Point(120, 55);
            this.numericPageNumber.Minimum = new decimal(new int[] {1, 0, 0, 0});
            this.numericPageNumber.Name = "numericPageNumber";
            this.numericPageNumber.Size = new System.Drawing.Size(60, 21);
            this.numericPageNumber.TabIndex = 3;
            this.numericPageNumber.Value = new decimal(new int[] {1, 0, 0, 0});
            
            // label1
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(20, 90);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(65, 12);
            this.label1.TabIndex = 4;
            this.label1.Text = "文本标注:";
            
            // txtAnnotationText
            this.txtAnnotationText.Location = new System.Drawing.Point(90, 85);
            this.txtAnnotationText.Name = "txtAnnotationText";
            this.txtAnnotationText.Size = new System.Drawing.Size(200, 21);
            this.txtAnnotationText.TabIndex = 5;
            
            // btnAddText
            this.btnAddText.Location = new System.Drawing.Point(300, 85);
            this.btnAddText.Name = "btnAddText";
            this.btnAddText.Size = new System.Drawing.Size(75, 25);
            this.btnAddText.TabIndex = 6;
            this.btnAddText.Text = "添加文本";
            this.btnAddText.Click += new System.EventHandler(this.btnAddText_Click);
            
            // btnLoadSignature
            this.btnLoadSignature.Location = new System.Drawing.Point(20, 120);
            this.btnLoadSignature.Name = "btnLoadSignature";
            this.btnLoadSignature.Size = new System.Drawing.Size(90, 25);
            this.btnLoadSignature.TabIndex = 7;
            this.btnLoadSignature.Text = "加载签名";
            this.btnLoadSignature.Click += new System.EventHandler(this.btnLoadSignature_Click);
            
            // pictureBoxSignature
            this.pictureBoxSignature.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.pictureBoxSignature.Location = new System.Drawing.Point(120, 120);
            this.pictureBoxSignature.Name = "pictureBoxSignature";
            this.pictureBoxSignature.Size = new System.Drawing.Size(100, 50);
            this.pictureBoxSignature.TabIndex = 8;
            this.pictureBoxSignature.TabStop = false;
            
            // btnAddSignature
            this.btnAddSignature.Location = new System.Drawing.Point(230, 120);
            this.btnAddSignature.Name = "btnAddSignature";
            this.btnAddSignature.Size = new System.Drawing.Size(75, 25);
            this.btnAddSignature.TabIndex = 9;
            this.btnAddSignature.Text = "添加签名";
            this.btnAddSignature.Click += new System.EventHandler(this.btnAddSignature_Click);
            
            // btnCaptureSignature
            this.btnCaptureSignature.Location = new System.Drawing.Point(20, 155);
            this.btnCaptureSignature.Name = "btnCaptureSignature";
            this.btnCaptureSignature.Size = new System.Drawing.Size(90, 25);
            this.btnCaptureSignature.TabIndex = 10;
            this.btnCaptureSignature.Text = "手写签名";
            this.btnCaptureSignature.Click += new System.EventHandler(this.btnCaptureSignature_Click);
            
            // btnSave
            this.btnSave.Location = new System.Drawing.Point(300, 155);
            this.btnSave.Name = "btnSave";
            this.btnSave.Size = new System.Drawing.Size(75, 25);
            this.btnSave.TabIndex = 11;
            this.btnSave.Text = "保存文档";
            this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
            
            // AnnotationForm
            this.ClientSize = new System.Drawing.Size(400, 200);
            this.Controls.Add(this.btnSave);
            this.Controls.Add(this.btnCaptureSignature);
            this.Controls.Add(this.btnAddSignature);
            this.Controls.Add(this.pictureBoxSignature);
            this.Controls.Add(this.btnLoadSignature);
            this.Controls.Add(this.btnAddText);
            this.Controls.Add(this.txtAnnotationText);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.numericPageNumber);
            this.Controls.Add(this.lblPageInfo);
            this.Controls.Add(this.btnSelectFile);
            this.Controls.Add(this.lblFileName);
            this.Name = "AnnotationForm";
            this.Text = "PDF标注工具";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            ((System.ComponentModel.ISupportInitialize)(this.numericPageNumber)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxSignature)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void btnSelectFile_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Filter = "PDF文件|*.pdf";
                openFileDialog.Title = "选择要标注的PDF文件";

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    pdfFilePath = openFileDialog.FileName;
                    lblFileName.Text = "文件: " + System.IO.Path.GetFileName(pdfFilePath);
                    LoadPdfPreview();
                }
            }
        }

        private void LoadPdfPreview()
        {
            try
            {
                using (PdfReader reader = new PdfReader(pdfFilePath))
                {
                    lblPageInfo.Text = "总页数: " + reader.NumberOfPages;
                    numericPageNumber.Maximum = reader.NumberOfPages;
                    numericPageNumber.Value = 1;
                    numericPageNumber.Enabled = true;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("读取PDF失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnLoadSignature_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Filter = "图片文件|*.png;*.jpg;*.bmp|所有文件|*.*";
                openFileDialog.Title = "选择签名图片";

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        signatureBitmap = new Bitmap(openFileDialog.FileName);
                        pictureBoxSignature.Image = signatureBitmap;
                        MessageBox.Show("签名加载成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("加载签名失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }

        private void btnCaptureSignature_Click(object sender, EventArgs e)
        {
            SignatureCaptureForm captureForm = new SignatureCaptureForm();
            if (captureForm.ShowDialog() == DialogResult.OK)
            {
                signatureBitmap = captureForm.GetSignature();
                pictureBoxSignature.Image = signatureBitmap;
                MessageBox.Show("手写签名已加载!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void btnAddText_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(pdfFilePath))
            {
                MessageBox.Show("请先选择PDF文件", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            if (string.IsNullOrEmpty(txtAnnotationText.Text))
            {
                MessageBox.Show("请输入标注文本", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            AddTextAnnotation(txtAnnotationText.Text, (int)numericPageNumber.Value);
        }

        private void btnAddSignature_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(pdfFilePath))
            {
                MessageBox.Show("请先选择PDF文件", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            if (signatureBitmap == null)
            {
                MessageBox.Show("请先加载或创建签名", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // 使用固定位置(右下角)
            AddSignatureAnnotation((int)numericPageNumber.Value, new Point(400, 50));
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(pdfFilePath))
            {
                MessageBox.Show("请先选择PDF文件", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // 检查是否进行了任何标注
            if (string.IsNullOrEmpty(txtAnnotationText.Text) && signatureBitmap == null)
            {
                MessageBox.Show("请先添加文本标注或签名", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            using (SaveFileDialog saveDialog = new SaveFileDialog())
            {
                saveDialog.Filter = "PDF文件|*.pdf";
                saveDialog.FileName = System.IO.Path.GetFileNameWithoutExtension(pdfFilePath) + "_annotated.pdf";
                saveDialog.Title = "保存标注后的PDF";

                if (saveDialog.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        // 创建标注后的PDF
                        CreateAnnotatedPdf(saveDialog.FileName);
                        MessageBox.Show("PDF保存成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("保存失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }

        private void CreateAnnotatedPdf(string outputPath)
        {
            using (FileStream fs = new FileStream(outputPath, FileMode.Create))
            using (PdfReader reader = new PdfReader(pdfFilePath))
            using (PdfStamper stamper = new PdfStamper(reader, fs))
            {
                // 添加文本标注
                if (!string.IsNullOrEmpty(txtAnnotationText.Text))
                {
                    PdfContentByte canvas = stamper.GetOverContent((int)numericPageNumber.Value);
                    
                    BaseFont baseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
                    canvas.SetFontAndSize(baseFont, 12);
                    canvas.SetRGBColorFill(255, 0, 0);
                    
                    canvas.BeginText();
                    canvas.ShowTextAligned(PdfContentByte.ALIGN_LEFT, txtAnnotationText.Text, 50, 700, 0);
                    canvas.EndText();
                }

                // 添加签名
                if (signatureBitmap != null)
                {
                    PdfContentByte canvas = stamper.GetOverContent((int)numericPageNumber.Value);
                    
                    MemoryStream ms = new MemoryStream();
                    signatureBitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                    iTextSharp.text.Image signatureImage = iTextSharp.text.Image.GetInstance(ms.GetBuffer());
                    
                    signatureImage.ScaleToFit(150, 80);
                    signatureImage.SetAbsolutePosition(400, 50);
                    
                    canvas.AddImage(signatureImage);
                }

                stamper.Close();
            }
        }

        private void AddTextAnnotation(string text, int pageNumber)
        {
            try
            {
                string tempPath = System.IO.Path.GetTempFileName() + ".pdf";
                CreateAnnotatedPdf(tempPath);
                
                // 替换原文件
                File.Copy(tempPath, pdfFilePath, true);
                File.Delete(tempPath);
                
                MessageBox.Show("文本标注添加成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show("添加标注失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void AddSignatureAnnotation(int pageNumber, Point position)
        {
            try
            {
                string tempPath = System.IO.Path.GetTempFileName() + ".pdf";
                CreateAnnotatedPdf(tempPath);
                
                // 替换原文件
                File.Copy(tempPath, pdfFilePath, true);
                File.Delete(tempPath);
                
                MessageBox.Show("签名添加成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show("添加签名失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}

DrawingPanelForm.cs

cs 复制代码
using System;
using System.Drawing;
using System.Windows.Forms;

namespace PDFTools
{
    public partial class DrawingPanelForm : Form
    {
        private Bitmap drawingBitmap;
        private Point previousPoint;
        private bool isDrawing = false;
        private Pen currentPen = new Pen(Color.Red, 2);
        private System.ComponentModel.IContainer components = null;

        private PictureBox pictureBoxDraw;
        private Button btnColorRed;
        private Button btnColorBlue;
        private Button btnColorGreen;
        private Button btnColorBlack;
        private Button btnClear;
        private Button btnSave;
        private Button btnCancel;

        public DrawingPanelForm()
        {
            InitializeComponent();
            currentPen.StartCap = System.Drawing.Drawing2D.LineCap.Round;
            currentPen.EndCap = System.Drawing.Drawing2D.LineCap.Round;
            drawingBitmap = new Bitmap(pictureBoxDraw.Width, pictureBoxDraw.Height);
            ClearCanvas();
        }

        private void InitializeComponent()
        {
            this.pictureBoxDraw = new System.Windows.Forms.PictureBox();
            this.btnColorRed = new System.Windows.Forms.Button();
            this.btnColorBlue = new System.Windows.Forms.Button();
            this.btnColorGreen = new System.Windows.Forms.Button();
            this.btnColorBlack = new System.Windows.Forms.Button();
            this.btnClear = new System.Windows.Forms.Button();
            this.btnSave = new System.Windows.Forms.Button();
            this.btnCancel = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxDraw)).BeginInit();
            this.SuspendLayout();
            
            // pictureBoxDraw
            this.pictureBoxDraw.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.pictureBoxDraw.Location = new System.Drawing.Point(20, 20);
            this.pictureBoxDraw.Name = "pictureBoxDraw";
            this.pictureBoxDraw.Size = new System.Drawing.Size(300, 150);
            this.pictureBoxDraw.TabIndex = 0;
            this.pictureBoxDraw.TabStop = false;
            this.pictureBoxDraw.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBoxDraw_MouseDown);
            this.pictureBoxDraw.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBoxDraw_MouseMove);
            this.pictureBoxDraw.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBoxDraw_MouseUp);
            
            // btnColorRed
            this.btnColorRed.BackColor = Color.Red;
            this.btnColorRed.Location = new System.Drawing.Point(20, 180);
            this.btnColorRed.Name = "btnColorRed";
            this.btnColorRed.Size = new System.Drawing.Size(30, 25);
            this.btnColorRed.TabIndex = 1;
            this.btnColorRed.Click += new System.EventHandler(this.btnColorRed_Click);
            
            // btnColorBlue
            this.btnColorBlue.BackColor = Color.Blue;
            this.btnColorBlue.Location = new System.Drawing.Point(60, 180);
            this.btnColorBlue.Name = "btnColorBlue";
            this.btnColorBlue.Size = new System.Drawing.Size(30, 25);
            this.btnColorBlue.TabIndex = 2;
            this.btnColorBlue.Click += new System.EventHandler(this.btnColorBlue_Click);
            
            // btnColorGreen
            this.btnColorGreen.BackColor = Color.Green;
            this.btnColorGreen.Location = new System.Drawing.Point(100, 180);
            this.btnColorGreen.Name = "btnColorGreen";
            this.btnColorGreen.Size = new System.Drawing.Size(30, 25);
            this.btnColorGreen.TabIndex = 3;
            this.btnColorGreen.Click += new System.EventHandler(this.btnColorGreen_Click);
            
            // btnColorBlack
            this.btnColorBlack.BackColor = Color.Black;
            this.btnColorBlack.ForeColor = Color.White;
            this.btnColorBlack.Location = new System.Drawing.Point(140, 180);
            this.btnColorBlack.Name = "btnColorBlack";
            this.btnColorBlack.Size = new System.Drawing.Size(30, 25);
            this.btnColorBlack.TabIndex = 4;
            this.btnColorBlack.Click += new System.EventHandler(this.btnColorBlack_Click);
            
            // btnClear
            this.btnClear.Location = new System.Drawing.Point(180, 180);
            this.btnClear.Name = "btnClear";
            this.btnClear.Size = new System.Drawing.Size(50, 25);
            this.btnClear.TabIndex = 5;
            this.btnClear.Text = "清除";
            this.btnClear.Click += new System.EventHandler(this.btnClear_Click);
            
            // btnSave
            this.btnSave.Location = new System.Drawing.Point(240, 180);
            this.btnSave.Name = "btnSave";
            this.btnSave.Size = new System.Drawing.Size(35, 25);
            this.btnSave.TabIndex = 6;
            this.btnSave.Text = "✓";
            this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
            
            // btnCancel
            this.btnCancel.Location = new System.Drawing.Point(285, 180);
            this.btnCancel.Name = "btnCancel";
            this.btnCancel.Size = new System.Drawing.Size(35, 25);
            this.btnCancel.TabIndex = 7;
            this.btnCancel.Text = "✗";
            this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
            
            // DrawingPanelForm
            this.ClientSize = new System.Drawing.Size(340, 220);
            this.Controls.Add(this.btnCancel);
            this.Controls.Add(this.btnSave);
            this.Controls.Add(this.btnClear);
            this.Controls.Add(this.btnColorBlack);
            this.Controls.Add(this.btnColorGreen);
            this.Controls.Add(this.btnColorBlue);
            this.Controls.Add(this.btnColorRed);
            this.Controls.Add(this.pictureBoxDraw);
            this.Name = "DrawingPanelForm";
            this.Text = "绘图面板";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxDraw)).EndInit();
            this.ResumeLayout(false);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        public Bitmap GetDrawing()
        {
            return drawingBitmap;
        }

        private void ClearCanvas()
        {
            using (Graphics g = Graphics.FromImage(drawingBitmap))
            {
                g.Clear(Color.Transparent);
            }
            pictureBoxDraw.Image = drawingBitmap;
        }

        private void pictureBoxDraw_MouseDown(object sender, MouseEventArgs e)
        {
            isDrawing = true;
            previousPoint = e.Location;
        }

        private void pictureBoxDraw_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDrawing)
            {
                using (Graphics g = Graphics.FromImage(drawingBitmap))
                {
                    g.DrawLine(currentPen, previousPoint, e.Location);
                }
                previousPoint = e.Location;
                pictureBoxDraw.Invalidate();
            }
        }

        private void pictureBoxDraw_MouseUp(object sender, MouseEventArgs e)
        {
            isDrawing = false;
        }

        private void btnColorRed_Click(object sender, EventArgs e)
        {
            currentPen.Color = Color.Red;
        }

        private void btnColorBlue_Click(object sender, EventArgs e)
        {
            currentPen.Color = Color.Blue;
        }

        private void btnColorGreen_Click(object sender, EventArgs e)
        {
            currentPen.Color = Color.Green;
        }

        private void btnColorBlack_Click(object sender, EventArgs e)
        {
            currentPen.Color = Color.Black;
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            ClearCanvas();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }
    }
}

MergeForm.cs

cs 复制代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;

namespace PDFTools
{
    public partial class MergeForm : Form
    {
        private List<string> selectedFiles = new List<string>();
        private Dictionary<string, List<int>> filePageNumbers = new Dictionary<string, List<int>>();

        public MergeForm()
        {
            InitializeComponent();
        }

        public void AddFile(string filePath)
        {
            if (File.Exists(filePath) && !selectedFiles.Contains(filePath))
            {
                selectedFiles.Add(filePath);
                UpdateFileList();
                LoadPageNumbers();
            }
        }

        private void UpdateFileList()
        {
            lstFiles.Items.Clear();
            foreach (string file in selectedFiles)
            {
                string pageInfo = "";
                if (filePageNumbers.ContainsKey(file))
                {
                    pageInfo = $" ({filePageNumbers[file].Count}页)";
                }
                lstFiles.Items.Add(System.IO.Path.GetFileName(file) + pageInfo);
            }
        }

        private void LoadPageNumbers()
        {
            filePageNumbers.Clear();
            foreach (string file in selectedFiles)
            {
                try
                {
                    List<int> pageNumbers = ExtractPageNumbersFromPdf(file);
                    filePageNumbers[file] = pageNumbers;
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"读取文件 {System.IO.Path.GetFileName(file)} 的页码失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private List<int> ExtractPageNumbersFromPdf(string filePath)
        {
            List<int> pageNumbers = new List<int>();
            
            using (PdfReader reader = new PdfReader(filePath))
            {
                int totalPages = reader.NumberOfPages;
                
                for (int i = 1; i <= totalPages; i++)
                {
                    int pageNumber = ExtractPageNumber(reader, i);
                    pageNumbers.Add(pageNumber);
                }
            }
            
            return pageNumbers;
        }

        private int ExtractPageNumber(PdfReader reader, int pageIndex)
        {
            try
            {
                // 方法1: 从页面元数据获取页码
                int pageNumberFromMetadata = TryExtractPageNumberFromMetadata(reader, pageIndex);
                if (pageNumberFromMetadata > 0)
                {
                    return pageNumberFromMetadata;
                }

                // 方法2: 从页面内容文本中提取页码
                int pageNumberFromContent = ExtractPageNumberFromContent(reader, pageIndex);
                if (pageNumberFromContent > 0)
                {
                    return pageNumberFromContent;
                }

                // 方法3: 从书签中获取页码信息
                int pageNumberFromBookmarks = GetPageNumberFromBookmarks(reader, pageIndex);
                if (pageNumberFromBookmarks > 0)
                {
                    return pageNumberFromBookmarks;
                }

                // 方法4: 使用顺序页码作为后备
                return pageIndex;
            }
            catch
            {
                return pageIndex;
            }
        }

        private int TryExtractPageNumberFromMetadata(PdfReader reader, int pageIndex)
        {
            try
            {
                // 尝试从文档信息中获取页码
                PdfDictionary pageDict = reader.GetPageN(pageIndex);
                if (pageDict != null)
                {
                    // 检查常见的页码存储字段
                    string[] possiblePageNumberFields = { "PageNumber", "P", "Page", "PageNo", "PageIndex" };
                    
                    foreach (string field in possiblePageNumberFields)
                    {
                        PdfObject numberObj = pageDict.Get(new PdfName(field));
                        if (numberObj != null && numberObj.IsNumber())
                        {
                            return ((PdfNumber)numberObj).IntValue;
                        }
                    }
                }
            }
            catch
            {
                // 忽略错误
            }
            return -1;
        }

        private int ExtractPageNumberFromContent(PdfReader reader, int pageIndex)
        {
            try
            {
                // 提取页面文本内容
                string pageText = ExtractTextFromPage(reader, pageIndex);
                
                if (!string.IsNullOrEmpty(pageText))
                {
                    // 在文本中查找页码模式
                    var matches = System.Text.RegularExpressions.Regex.Matches(pageText, @"\b(\d{1,3})\b");
                    foreach (System.Text.RegularExpressions.Match match in matches)
                    {
                        if (int.TryParse(match.Value, out int number))
                        {
                            // 简单的启发式规则:页码通常在1到500之间
                            if (number > 0 && number < 500)
                            {
                                return number;
                            }
                        }
                    }

                    // 查找页眉页脚中的页码
                    var footerMatches = System.Text.RegularExpressions.Regex.Matches(pageText, @"第\s*(\d+)\s*页");
                    foreach (System.Text.RegularExpressions.Match match in footerMatches)
                    {
                        if (match.Groups.Count > 1 && int.TryParse(match.Groups[1].Value, out int number))
                        {
                            return number;
                        }
                    }
                }
            }
            catch
            {
                // 忽略错误
            }
            return -1;
        }

        private string ExtractTextFromPage(PdfReader reader, int pageIndex)
        {
            try
            {
                // 使用iTextSharp提取文本
                return PdfTextExtractor.GetTextFromPage(reader, pageIndex);
            }
            catch
            {
                return string.Empty;
            }
        }

        private int GetPageNumberFromBookmarks(PdfReader reader, int pageIndex)
        {
            try
            {
                // 获取书签列表
                IList<Dictionary<string, object>> bookmarks = SimpleBookmark.GetBookmark(reader);
                if (bookmarks != null)
                {
                    foreach (var bookmark in bookmarks)
                    {
                        if (bookmark.ContainsKey("Page"))
                        {
                            string pageRef = bookmark["Page"].ToString();
                            if (pageRef.Contains($" {pageIndex} "))
                            {
                                if (bookmark.ContainsKey("Title") && 
                                    int.TryParse(bookmark["Title"].ToString(), out int pageNumber))
                                {
                                    return pageNumber;
                                }
                            }
                        }
                    }
                }
            }
            catch
            {
                // 忽略错误
            }
            return -1;
        }

        private void btnSelectFiles_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Filter = "PDF文件|*.pdf";
                openFileDialog.Multiselect = true;
                openFileDialog.Title = "选择要合并的PDF文件";

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    selectedFiles.AddRange(openFileDialog.FileNames);
                    UpdateFileList();
                    LoadPageNumbers();
                }
            }
        }

        private void btnRemoveSelected_Click(object sender, EventArgs e)
        {
            if (lstFiles.SelectedIndex != -1)
            {
                selectedFiles.RemoveAt(lstFiles.SelectedIndex);
                UpdateFileList();
                LoadPageNumbers();
            }
        }

        private void btnClearAll_Click(object sender, EventArgs e)
        {
            selectedFiles.Clear();
            filePageNumbers.Clear();
            UpdateFileList();
        }

        private void btnMoveUp_Click(object sender, EventArgs e)
        {
            if (lstFiles.SelectedIndex > 0)
            {
                int selectedIndex = lstFiles.SelectedIndex;
                string temp = selectedFiles[selectedIndex];
                selectedFiles[selectedIndex] = selectedFiles[selectedIndex - 1];
                selectedFiles[selectedIndex - 1] = temp;
                UpdateFileList();
                lstFiles.SelectedIndex = selectedIndex - 1;
                LoadPageNumbers();
            }
        }

        private void btnMoveDown_Click(object sender, EventArgs e)
        {
            if (lstFiles.SelectedIndex != -1 && lstFiles.SelectedIndex < selectedFiles.Count - 1)
            {
                int selectedIndex = lstFiles.SelectedIndex;
                string temp = selectedFiles[selectedIndex];
                selectedFiles[selectedIndex] = selectedFiles[selectedIndex + 1];
                selectedFiles[selectedIndex + 1] = temp;
                UpdateFileList();
                lstFiles.SelectedIndex = selectedIndex + 1;
                LoadPageNumbers();
            }
        }

        private void btnMerge_Click(object sender, EventArgs e)
        {
            if (selectedFiles.Count < 2)
            {
                MessageBox.Show("请至少选择两个PDF文件进行合并", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            if (string.IsNullOrEmpty(txtOutputFileName.Text))
            {
                MessageBox.Show("请输入输出文件名", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // 选择合并方式
            using (var mergeOptionForm = new MergeOptionForm())
            {
                if (mergeOptionForm.ShowDialog() == DialogResult.OK)
                {
                    using (SaveFileDialog saveFileDialog = new SaveFileDialog())
                    {
                        saveFileDialog.Filter = "PDF文件|*.pdf";
                        saveFileDialog.FileName = txtOutputFileName.Text;
                        saveFileDialog.Title = "选择输出位置";

                        if (saveFileDialog.ShowDialog() == DialogResult.OK)
                        {
                            try
                            {
                                if (mergeOptionForm.MergeByPageOrder)
                                {
                                    MergePdfFilesByPageOrder(selectedFiles, saveFileDialog.FileName);
                                }
                                else
                                {
                                    MergePdfFiles(selectedFiles, saveFileDialog.FileName);
                                }
                                MessageBox.Show("PDF合并完成!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show("合并失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                        }
                    }
                }
            }
        }

        // 原有的简单合并方法(按文件顺序)
        private void MergePdfFiles(List<string> inputFiles, string outputFile)
        {
            int totalPages = 0;

            using (Document document = new Document())
            using (FileStream fs = new FileStream(outputFile, FileMode.Create))
            using (PdfCopy copy = new PdfCopy(document, fs))
            {
                document.Open();

                foreach (string file in inputFiles)
                {
                    if (!File.Exists(file))
                    {
                        throw new FileNotFoundException("文件不存在: " + file);
                    }

                    using (PdfReader reader = new PdfReader(file))
                    {
                        int pageCount = reader.NumberOfPages;
                        totalPages += pageCount;

                        for (int i = 1; i <= pageCount; i++)
                        {
                            copy.AddPage(copy.GetImportedPage(reader, i));
                        }
                    }
                }

                document.Close();
            }
        }

        // 新的按页码合并方法
        private void MergePdfFilesByPageOrder(List<string> inputFiles, string outputFile)
        {
            // 获取所有页面的信息
            var allPages = new List<(string file, int actualPageNumber, int physicalPageIndex)>();

            foreach (string file in inputFiles)
            {
                if (filePageNumbers.ContainsKey(file))
                {
                    var pageNumbers = filePageNumbers[file];
                    for (int i = 0; i < pageNumbers.Count; i++)
                    {
                        allPages.Add((file, pageNumbers[i], i + 1)); // i+1 是物理页码
                    }
                }
            }

            // 按实际页码排序
            var sortedPages = allPages.OrderBy(p => p.actualPageNumber).ToList();

            using (Document document = new Document())
            using (FileStream fs = new FileStream(outputFile, FileMode.Create))
            using (PdfCopy copy = new PdfCopy(document, fs))
            {
                document.Open();

                foreach (var pageInfo in sortedPages)
                {
                    using (PdfReader reader = new PdfReader(pageInfo.file))
                    {
                        copy.AddPage(copy.GetImportedPage(reader, pageInfo.physicalPageIndex));
                    }
                }

                document.Close();
            }
        }

        private void btnPreview_Click(object sender, EventArgs e)
        {
            if (lstFiles.SelectedIndex >= 0 && lstFiles.SelectedIndex < selectedFiles.Count)
            {
                OpenPdfWithDefaultProgram(selectedFiles[lstFiles.SelectedIndex]);
            }
            else if (selectedFiles.Count > 0)
            {
                OpenPdfWithDefaultProgram(selectedFiles[0]);
            }
            else
            {
                MessageBox.Show("请先选择PDF文件", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void OpenPdfWithDefaultProgram(string filePath)
        {
            try
            {
                System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
                {
                    FileName = filePath,
                    UseShellExecute = true
                });
            }
            catch (Exception ex)
            {
                MessageBox.Show("无法打开文件: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void lstFiles_SelectedIndexChanged(object sender, EventArgs e)
        {
            // 可以在这里添加选中文件时的处理逻辑
        }
    }
}

MergeForm.Designer.cs

cs 复制代码
namespace PDFTools
{
    partial class MergeForm
    {
        /// <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.btnSelectFiles = new System.Windows.Forms.Button();
            this.btnPreview = new System.Windows.Forms.Button();
            this.lstFiles = new System.Windows.Forms.ListBox();
            this.btnRemoveSelected = new System.Windows.Forms.Button();
            this.btnClearAll = new System.Windows.Forms.Button();
            this.btnMoveUp = new System.Windows.Forms.Button();
            this.btnMoveDown = new System.Windows.Forms.Button();
            this.label1 = new System.Windows.Forms.Label();
            this.txtOutputFileName = new System.Windows.Forms.TextBox();
            this.btnMerge = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // btnSelectFiles
            // 
            this.btnSelectFiles.Location = new System.Drawing.Point(20, 20);
            this.btnSelectFiles.Name = "btnSelectFiles";
            this.btnSelectFiles.Size = new System.Drawing.Size(120, 30);
            this.btnSelectFiles.TabIndex = 0;
            this.btnSelectFiles.Text = "选择PDF文件";
            this.btnSelectFiles.UseVisualStyleBackColor = true;
            this.btnSelectFiles.Click += new System.EventHandler(this.btnSelectFiles_Click);
            // 
            // btnPreview
            // 
            this.btnPreview.Location = new System.Drawing.Point(150, 20);
            this.btnPreview.Name = "btnPreview";
            this.btnPreview.Size = new System.Drawing.Size(120, 30);
            this.btnPreview.TabIndex = 1;
            this.btnPreview.Text = "打开PDF文件";
            this.btnPreview.UseVisualStyleBackColor = true;
            this.btnPreview.Click += new System.EventHandler(this.btnPreview_Click);
            // 
            // lstFiles
            // 
            this.lstFiles.FormattingEnabled = true;
            this.lstFiles.ItemHeight = 12;
            this.lstFiles.Location = new System.Drawing.Point(20, 60);
            this.lstFiles.Name = "lstFiles";
            this.lstFiles.Size = new System.Drawing.Size(250, 160);
            this.lstFiles.TabIndex = 2;
            this.lstFiles.SelectedIndexChanged += new System.EventHandler(this.lstFiles_SelectedIndexChanged);
            // 
            // btnRemoveSelected
            // 
            this.btnRemoveSelected.Location = new System.Drawing.Point(280, 60);
            this.btnRemoveSelected.Name = "btnRemoveSelected";
            this.btnRemoveSelected.Size = new System.Drawing.Size(80, 30);
            this.btnRemoveSelected.TabIndex = 3;
            this.btnRemoveSelected.Text = "删除选中";
            this.btnRemoveSelected.UseVisualStyleBackColor = true;
            this.btnRemoveSelected.Click += new System.EventHandler(this.btnRemoveSelected_Click);
            // 
            // btnClearAll
            // 
            this.btnClearAll.Location = new System.Drawing.Point(280, 100);
            this.btnClearAll.Name = "btnClearAll";
            this.btnClearAll.Size = new System.Drawing.Size(80, 30);
            this.btnClearAll.TabIndex = 4;
            this.btnClearAll.Text = "清空列表";
            this.btnClearAll.UseVisualStyleBackColor = true;
            this.btnClearAll.Click += new System.EventHandler(this.btnClearAll_Click);
            // 
            // btnMoveUp
            // 
            this.btnMoveUp.Location = new System.Drawing.Point(280, 140);
            this.btnMoveUp.Name = "btnMoveUp";
            this.btnMoveUp.Size = new System.Drawing.Size(80, 30);
            this.btnMoveUp.TabIndex = 5;
            this.btnMoveUp.Text = "上移";
            this.btnMoveUp.UseVisualStyleBackColor = true;
            this.btnMoveUp.Click += new System.EventHandler(this.btnMoveUp_Click);
            // 
            // btnMoveDown
            // 
            this.btnMoveDown.Location = new System.Drawing.Point(280, 180);
            this.btnMoveDown.Name = "btnMoveDown";
            this.btnMoveDown.Size = new System.Drawing.Size(80, 30);
            this.btnMoveDown.TabIndex = 6;
            this.btnMoveDown.Text = "下移";
            this.btnMoveDown.UseVisualStyleBackColor = true;
            this.btnMoveDown.Click += new System.EventHandler(this.btnMoveDown_Click);
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(20, 230);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(89, 12);
            this.label1.TabIndex = 7;
            this.label1.Text = "输出文件名:";
            // 
            // txtOutputFileName
            // 
            this.txtOutputFileName.Location = new System.Drawing.Point(115, 227);
            this.txtOutputFileName.Name = "txtOutputFileName";
            this.txtOutputFileName.Size = new System.Drawing.Size(155, 21);
            this.txtOutputFileName.TabIndex = 8;
            this.txtOutputFileName.Text = "merged_document";
            // 
            // btnMerge
            // 
            this.btnMerge.Location = new System.Drawing.Point(280, 225);
            this.btnMerge.Name = "btnMerge";
            this.btnMerge.Size = new System.Drawing.Size(80, 30);
            this.btnMerge.TabIndex = 9;
            this.btnMerge.Text = "开始合并";
            this.btnMerge.UseVisualStyleBackColor = true;
            this.btnMerge.Click += new System.EventHandler(this.btnMerge_Click);
            // 
            // MergeForm
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(380, 280);
            this.Controls.Add(this.btnMerge);
            this.Controls.Add(this.txtOutputFileName);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.btnMoveDown);
            this.Controls.Add(this.btnMoveUp);
            this.Controls.Add(this.btnClearAll);
            this.Controls.Add(this.btnRemoveSelected);
            this.Controls.Add(this.lstFiles);
            this.Controls.Add(this.btnPreview);
            this.Controls.Add(this.btnSelectFiles);
            this.Name = "MergeForm";
            this.Text = "PDF合并";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button btnSelectFiles;
        private System.Windows.Forms.Button btnPreview;
        private System.Windows.Forms.ListBox lstFiles;
        private System.Windows.Forms.Button btnRemoveSelected;
        private System.Windows.Forms.Button btnClearAll;
        private System.Windows.Forms.Button btnMoveUp;
        private System.Windows.Forms.Button btnMoveDown;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.TextBox txtOutputFileName;
        private System.Windows.Forms.Button btnMerge;
    }
}

MergeOptionForm.cs

cs 复制代码
using System;
using System.Windows.Forms;

namespace PDFTools
{
    public partial class MergeOptionForm : Form
    {
        // 使用字段而不是自动属性
        private bool mergeByPageOrder = false;

        public bool MergeByPageOrder 
        { 
            get { return mergeByPageOrder; }
        }

        private RadioButton rbFileOrder;
        private RadioButton rbPageOrder;
        private Button btnOK;
        private Button btnCancel;
        private Label label1;

        public MergeOptionForm()
        {
            InitializeComponent();
        }

        private void InitializeComponent()
        {
            this.rbFileOrder = new System.Windows.Forms.RadioButton();
            this.rbPageOrder = new System.Windows.Forms.RadioButton();
            this.btnOK = new System.Windows.Forms.Button();
            this.btnCancel = new System.Windows.Forms.Button();
            this.label1 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            
            // rbFileOrder
            this.rbFileOrder.AutoSize = true;
            this.rbFileOrder.Checked = true;
            this.rbFileOrder.Location = new System.Drawing.Point(20, 50);
            this.rbFileOrder.Name = "rbFileOrder";
            this.rbFileOrder.Size = new System.Drawing.Size(191, 16);
            this.rbFileOrder.TabIndex = 0;
            this.rbFileOrder.TabStop = true;
            this.rbFileOrder.Text = "按文件顺序合并(文件1→文件2)";
            this.rbFileOrder.UseVisualStyleBackColor = true;
            
            // rbPageOrder
            this.rbPageOrder.AutoSize = true;
            this.rbPageOrder.Location = new System.Drawing.Point(20, 80);
            this.rbPageOrder.Name = "rbPageOrder";
            this.rbPageOrder.Size = new System.Drawing.Size(239, 16);
            this.rbPageOrder.TabIndex = 1;
            this.rbPageOrder.Text = "按页码顺序合并(第1页→第2页→第3页)";
            this.rbPageOrder.UseVisualStyleBackColor = true;
            
            // btnOK
            this.btnOK.Location = new System.Drawing.Point(70, 120);
            this.btnOK.Name = "btnOK";
            this.btnOK.Size = new System.Drawing.Size(75, 25);
            this.btnOK.TabIndex = 2;
            this.btnOK.Text = "确定";
            this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
            
            // btnCancel
            this.btnCancel.Location = new System.Drawing.Point(160, 120);
            this.btnCancel.Name = "btnCancel";
            this.btnCancel.Size = new System.Drawing.Size(75, 25);
            this.btnCancel.TabIndex = 3;
            this.btnCancel.Text = "取消";
            this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
            
            // label1
            this.label1.AutoSize = true;
            this.label1.Font = new System.Drawing.Font("微软雅黑", 10F, System.Drawing.FontStyle.Bold);
            this.label1.Location = new System.Drawing.Point(20, 20);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(111, 19);
            this.label1.TabIndex = 4;
            this.label1.Text = "选择合并方式:";
            
            // MergeOptionForm
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(300, 160);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.btnCancel);
            this.Controls.Add(this.btnOK);
            this.Controls.Add(this.rbPageOrder);
            this.Controls.Add(this.rbFileOrder);
            this.Name = "MergeOptionForm";
            this.Text = "合并选项";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            mergeByPageOrder = rbPageOrder.Checked;
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }
    }
}

PdfPreviewForm.cs

cs 复制代码
using System;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;

namespace PDFTools
{
    public partial class PdfPreviewForm : Form
    {
        private string pdfFilePath;

        public PdfPreviewForm(string filePath)
        {
            InitializeComponent();
            pdfFilePath = filePath;
            this.Text = "PDF预览 - " + Path.GetFileName(filePath);
        }

        private void InitializeComponent()
        {
            this.btnOpenWithDefault = new System.Windows.Forms.Button();
            this.lblInfo = new System.Windows.Forms.Label();
            this.pictureBoxThumbnail = new System.Windows.Forms.PictureBox();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxThumbnail)).BeginInit();
            this.SuspendLayout();
            
            // btnOpenWithDefault
            this.btnOpenWithDefault.Location = new System.Drawing.Point(20, 20);
            this.btnOpenWithDefault.Name = "btnOpenWithDefault";
            this.btnOpenWithDefault.Size = new System.Drawing.Size(150, 30);
            this.btnOpenWithDefault.TabIndex = 0;
            this.btnOpenWithDefault.Text = "用默认程序打开";
            this.btnOpenWithDefault.Click += new System.EventHandler(this.btnOpenWithDefault_Click);
            
            // lblInfo
            this.lblInfo.AutoSize = true;
            this.lblInfo.Location = new System.Drawing.Point(20, 70);
            this.lblInfo.Name = "lblInfo";
            this.lblInfo.Size = new System.Drawing.Size(0, 12);
            this.lblInfo.TabIndex = 1;
            
            // pictureBoxThumbnail
            this.pictureBoxThumbnail.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.pictureBoxThumbnail.Location = new System.Drawing.Point(20, 100);
            this.pictureBoxThumbnail.Name = "pictureBoxThumbnail";
            this.pictureBoxThumbnail.Size = new System.Drawing.Size(200, 200);
            this.pictureBoxThumbnail.TabIndex = 2;
            this.pictureBoxThumbnail.TabStop = false;
            
            // PdfPreviewForm
            this.ClientSize = new System.Drawing.Size(400, 350);
            this.Controls.Add(this.pictureBoxThumbnail);
            this.Controls.Add(this.lblInfo);
            this.Controls.Add(this.btnOpenWithDefault);
            this.Name = "PdfPreviewForm";
            this.Text = "PDF预览";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Load += new System.EventHandler(this.PdfPreviewForm_Load);
            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxThumbnail)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        private void PdfPreviewForm_Load(object sender, EventArgs e)
        {
            try
            {
                FileInfo fileInfo = new FileInfo(pdfFilePath);
                lblInfo.Text = $"文件名: {fileInfo.Name}\n大小: {fileInfo.Length / 1024} KB\n创建时间: {fileInfo.CreationTime}";
                
                // 创建简单的PDF图标
                CreatePdfThumbnail();
            }
            catch (Exception ex)
            {
                lblInfo.Text = "无法获取文件信息: " + ex.Message;
            }
        }

        private void CreatePdfThumbnail()
        {
            // 创建一个简单的PDF图标
            using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(200, 200))
            using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp))
            {
                g.Clear(System.Drawing.Color.White);
                
                // 绘制PDF文档图标
                g.DrawRectangle(System.Drawing.Pens.Black, 10, 10, 180, 180);
                g.DrawLine(System.Drawing.Pens.Black, 10, 40, 190, 40);
                g.DrawLine(System.Drawing.Pens.Black, 10, 70, 190, 70);
                g.DrawLine(System.Drawing.Pens.Black, 10, 100, 190, 100);
                
                // 绘制文字
                g.DrawString("PDF文档", new System.Drawing.Font("Arial", 12), System.Drawing.Brushes.Black, 60, 150);
                g.DrawString("预览", new System.Drawing.Font("Arial", 10), System.Drawing.Brushes.Blue, 80, 170);
                
                pictureBoxThumbnail.Image = (System.Drawing.Image)bmp.Clone();
            }
        }

        private void btnOpenWithDefault_Click(object sender, EventArgs e)
        {
            try
            {
                Process.Start(new ProcessStartInfo
                {
                    FileName = pdfFilePath,
                    UseShellExecute = true
                });
            }
            catch (Exception ex)
            {
                MessageBox.Show("无法打开文件: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private System.Windows.Forms.Button btnOpenWithDefault;
        private System.Windows.Forms.Label lblInfo;
        private System.Windows.Forms.PictureBox pictureBoxThumbnail;
    }
}

PDFTools.csproj

cs 复制代码
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net9.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <UseWindowsForms>true</UseWindowsForms>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="iTextSharp" Version="5.5.13.4" />
    <PackageReference Include="PdfiumViewer" Version="2.13.0" />
    <PackageReference Include="System.Drawing.Common" Version="9.0.8" />
  </ItemGroup>

</Project>

PDFTools.csproj.user

cs 复制代码
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <Compile Update="Form1.cs">
            <SubType>Form</SubType>
        </Compile>
    </ItemGroup>
</Project>

Program.cs

cs 复制代码
using System;
using System.Windows.Forms;

namespace PDFTools
{
    internal static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
    }
}

SignatureCaptureForm.cs

cs 复制代码
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Windows.Forms;

namespace PDFTools
{
    public partial class SignatureCaptureForm : Form
    {
        private Bitmap signatureBitmap;
        private Point previousPoint;
        private bool isDrawing = false;
        private Pen drawingPen = new Pen(Color.Black, 3);

        public SignatureCaptureForm()
        {
            InitializeComponent();
            drawingPen.StartCap = LineCap.Round;
            drawingPen.EndCap = LineCap.Round;
            signatureBitmap = new Bitmap(pictureBoxSignature.Width, pictureBoxSignature.Height);
            ClearCanvas();
        }

        private void InitializeComponent()
        {
            this.pictureBoxSignature = new System.Windows.Forms.PictureBox();
            this.btnClear = new System.Windows.Forms.Button();
            this.btnSave = new System.Windows.Forms.Button();
            this.btnCancel = new System.Windows.Forms.Button();
            this.btnColorBlack = new System.Windows.Forms.Button();
            this.btnColorBlue = new System.Windows.Forms.Button();
            this.btnColorRed = new System.Windows.Forms.Button();
            this.label1 = new System.Windows.Forms.Label();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxSignature)).BeginInit();
            this.SuspendLayout();
            
            // pictureBoxSignature
            this.pictureBoxSignature.BackColor = Color.White;
            this.pictureBoxSignature.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.pictureBoxSignature.Location = new System.Drawing.Point(20, 40);
            this.pictureBoxSignature.Name = "pictureBoxSignature";
            this.pictureBoxSignature.Size = new System.Drawing.Size(400, 200);
            this.pictureBoxSignature.TabIndex = 0;
            this.pictureBoxSignature.TabStop = false;
            this.pictureBoxSignature.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBoxSignature_MouseDown);
            this.pictureBoxSignature.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBoxSignature_MouseMove);
            this.pictureBoxSignature.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBoxSignature_MouseUp);
            
            // btnClear
            this.btnClear.Location = new System.Drawing.Point(20, 250);
            this.btnClear.Name = "btnClear";
            this.btnClear.Size = new System.Drawing.Size(80, 30);
            this.btnClear.TabIndex = 1;
            this.btnClear.Text = "清除";
            this.btnClear.Click += new System.EventHandler(this.btnClear_Click);
            
            // btnSave
            this.btnSave.Location = new System.Drawing.Point(180, 250);
            this.btnSave.Name = "btnSave";
            this.btnSave.Size = new System.Drawing.Size(80, 30);
            this.btnSave.TabIndex = 2;
            this.btnSave.Text = "保存";
            this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
            
            // btnCancel
            this.btnCancel.Location = new System.Drawing.Point(340, 250);
            this.btnCancel.Name = "btnCancel";
            this.btnCancel.Size = new System.Drawing.Size(80, 30);
            this.btnCancel.TabIndex = 3;
            this.btnCancel.Text = "取消";
            this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
            
            // btnColorBlack
            this.btnColorBlack.BackColor = Color.Black;
            this.btnColorBlack.ForeColor = Color.White;
            this.btnColorBlack.Location = new System.Drawing.Point(20, 10);
            this.btnColorBlack.Name = "btnColorBlack";
            this.btnColorBlack.Size = new System.Drawing.Size(30, 25);
            this.btnColorBlack.TabIndex = 4;
            this.btnColorBlack.Text = "黑";
            this.btnColorBlack.Click += new System.EventHandler(this.btnColorBlack_Click);
            
            // btnColorBlue
            this.btnColorBlue.BackColor = Color.Blue;
            this.btnColorBlue.ForeColor = Color.White;
            this.btnColorBlue.Location = new System.Drawing.Point(60, 10);
            this.btnColorBlue.Name = "btnColorBlue";
            this.btnColorBlue.Size = new System.Drawing.Size(30, 25);
            this.btnColorBlue.TabIndex = 5;
            this.btnColorBlue.Text = "蓝";
            this.btnColorBlue.Click += new System.EventHandler(this.btnColorBlue_Click);
            
            // btnColorRed
            this.btnColorRed.BackColor = Color.Red;
            this.btnColorRed.ForeColor = Color.White;
            this.btnColorRed.Location = new System.Drawing.Point(100, 10);
            this.btnColorRed.Name = "btnColorRed";
            this.btnColorRed.Size = new System.Drawing.Size(30, 25);
            this.btnColorRed.TabIndex = 6;
            this.btnColorRed.Text = "红";
            this.btnColorRed.Click += new System.EventHandler(this.btnColorRed_Click);
            
            // label1
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(150, 15);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(149, 12);
            this.label1.TabIndex = 7;
            this.label1.Text = "请在下方区域手写签名:";
            
            // SignatureCaptureForm
            this.ClientSize = new System.Drawing.Size(440, 300);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.btnColorRed);
            this.Controls.Add(this.btnColorBlue);
            this.Controls.Add(this.btnColorBlack);
            this.Controls.Add(this.btnCancel);
            this.Controls.Add(this.btnSave);
            this.Controls.Add(this.btnClear);
            this.Controls.Add(this.pictureBoxSignature);
            this.Name = "SignatureCaptureForm";
            this.Text = "手写签名";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxSignature)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        public Bitmap GetSignature()
        {
            return signatureBitmap;
        }

        public string SaveSignatureToFile()
        {
            using (SaveFileDialog saveDialog = new SaveFileDialog())
            {
                saveDialog.Filter = "PNG图片|*.png";
                saveDialog.FileName = "signature_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".png";
                saveDialog.Title = "保存签名";

                if (saveDialog.ShowDialog() == DialogResult.OK)
                {
                    signatureBitmap.Save(saveDialog.FileName, System.Drawing.Imaging.ImageFormat.Png);
                    return saveDialog.FileName;
                }
            }
            return null;
        }

        private void ClearCanvas()
        {
            using (Graphics g = Graphics.FromImage(signatureBitmap))
            {
                g.Clear(Color.White);
            }
            pictureBoxSignature.Image = signatureBitmap;
        }

        private void pictureBoxSignature_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isDrawing = true;
                previousPoint = e.Location;
            }
        }

        private void pictureBoxSignature_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDrawing && e.Button == MouseButtons.Left)
            {
                using (Graphics g = Graphics.FromImage(signatureBitmap))
                {
                    g.DrawLine(drawingPen, previousPoint, e.Location);
                }
                previousPoint = e.Location;
                pictureBoxSignature.Invalidate();
            }
        }

        private void pictureBoxSignature_MouseUp(object sender, MouseEventArgs e)
        {
            isDrawing = false;
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            ClearCanvas();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            // 检查是否有签名内容
            if (IsCanvasEmpty())
            {
                MessageBox.Show("请先书写签名", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            string savedPath = SaveSignatureToFile();
            if (!string.IsNullOrEmpty(savedPath))
            {
                MessageBox.Show("签名保存成功!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        private bool IsCanvasEmpty()
        {
            // 检查画布是否为空(只有白色)
            for (int x = 0; x < signatureBitmap.Width; x++)
            {
                for (int y = 0; y < signatureBitmap.Height; y++)
                {
                    if (signatureBitmap.GetPixel(x, y).ToArgb() != Color.White.ToArgb())
                    {
                        return false;
                    }
                }
            }
            return true;
        }

        private void btnColorBlack_Click(object sender, EventArgs e)
        {
            drawingPen.Color = Color.Black;
        }

        private void btnColorBlue_Click(object sender, EventArgs e)
        {
            drawingPen.Color = Color.Blue;
        }

        private void btnColorRed_Click(object sender, EventArgs e)
        {
            drawingPen.Color = Color.Red;
        }

        private System.Windows.Forms.PictureBox pictureBoxSignature;
        private System.Windows.Forms.Button btnClear;
        private System.Windows.Forms.Button btnSave;
        private System.Windows.Forms.Button btnCancel;
        private System.Windows.Forms.Button btnColorBlack;
        private System.Windows.Forms.Button btnColorBlue;
        private System.Windows.Forms.Button btnColorRed;
        private System.Windows.Forms.Label label1;
    }
}

SignaturePositionForm.cs

cs 复制代码
using System;
using System.Drawing;
using System.Windows.Forms;

namespace PDFTools
{
    public partial class SignaturePositionForm : Form
    {
        // 使用字段而不是自动属性
        private Point selectedPosition = new Point(50, 50);

        public Point SelectedPosition 
        { 
            get { return selectedPosition; }
        }

        private TrackBar trackBarX;
        private TrackBar trackBarY;
        private Label labelX;
        private Label labelY;
        private Label labelValueX;
        private Label labelValueY;
        private Button btnOK;
        private Button btnCancel;

        public SignaturePositionForm()
        {
            InitializeComponent();
            UpdatePositionLabels();
        }

        private void InitializeComponent()
        {
            this.trackBarX = new System.Windows.Forms.TrackBar();
            this.trackBarY = new System.Windows.Forms.TrackBar();
            this.labelX = new System.Windows.Forms.Label();
            this.labelY = new System.Windows.Forms.Label();
            this.labelValueX = new System.Windows.Forms.Label();
            this.labelValueY = new System.Windows.Forms.Label();
            this.btnOK = new System.Windows.Forms.Button();
            this.btnCancel = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this.trackBarX)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.trackBarY)).BeginInit();
            this.SuspendLayout();
            
            // trackBarX (X坐标滑动条)
            this.trackBarX.Location = new System.Drawing.Point(50, 20);
            this.trackBarX.Minimum = 10;
            this.trackBarX.Maximum = 500;
            this.trackBarX.Name = "trackBarX";
            this.trackBarX.Size = new System.Drawing.Size(200, 45);
            this.trackBarX.TabIndex = 0;
            this.trackBarX.Value = 50;
            this.trackBarX.Scroll += new System.EventHandler(this.trackBar_Scroll);
            
            // trackBarY (Y坐标滑动条)
            this.trackBarY.Location = new System.Drawing.Point(50, 70);
            this.trackBarY.Minimum = 10;
            this.trackBarY.Maximum = 800;
            this.trackBarY.Name = "trackBarY";
            this.trackBarY.Size = new System.Drawing.Size(200, 45);
            this.trackBarY.TabIndex = 1;
            this.trackBarY.Value = 50;
            this.trackBarY.Scroll += new System.EventHandler(this.trackBar_Scroll);
            
            // labelX
            this.labelX.AutoSize = true;
            this.labelX.Location = new System.Drawing.Point(20, 25);
            this.labelX.Name = "labelX";
            this.labelX.Size = new System.Drawing.Size(23, 12);
            this.labelX.TabIndex = 2;
            this.labelX.Text = "X:";
            
            // labelY
            this.labelY.AutoSize = true;
            this.labelY.Location = new System.Drawing.Point(20, 75);
            this.labelY.Name = "labelY";
            this.labelY.Size = new System.Drawing.Size(23, 12);
            this.labelY.TabIndex = 3;
            this.labelY.Text = "Y:";
            
            // labelValueX
            this.labelValueX.AutoSize = true;
            this.labelValueX.Location = new System.Drawing.Point(260, 25);
            this.labelValueX.Name = "labelValueX";
            this.labelValueX.Size = new System.Drawing.Size(29, 12);
            this.labelValueX.TabIndex = 4;
            this.labelValueX.Text = "50px";
            
            // labelValueY
            this.labelValueY.AutoSize = true;
            this.labelValueY.Location = new System.Drawing.Point(260, 75);
            this.labelValueY.Name = "labelValueY";
            this.labelValueY.Size = new System.Drawing.Size(29, 12);
            this.labelValueY.TabIndex = 5;
            this.labelValueY.Text = "50px";
            
            // btnOK
            this.btnOK.Location = new System.Drawing.Point(70, 120);
            this.btnOK.Name = "btnOK";
            this.btnOK.Size = new System.Drawing.Size(75, 25);
            this.btnOK.TabIndex = 6;
            this.btnOK.Text = "确定";
            this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
            
            // btnCancel
            this.btnCancel.Location = new System.Drawing.Point(160, 120);
            this.btnCancel.Name = "btnCancel";
            this.btnCancel.Size = new System.Drawing.Size(75, 25);
            this.btnCancel.TabIndex = 7;
            this.btnCancel.Text = "取消";
            this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
            
            // SignaturePositionForm
            this.ClientSize = new System.Drawing.Size(320, 160);
            this.Controls.Add(this.btnCancel);
            this.Controls.Add(this.btnOK);
            this.Controls.Add(this.labelValueY);
            this.Controls.Add(this.labelValueX);
            this.Controls.Add(this.labelY);
            this.Controls.Add(this.labelX);
            this.Controls.Add(this.trackBarY);
            this.Controls.Add(this.trackBarX);
            this.Name = "SignaturePositionForm";
            this.Text = "选择签名位置";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            ((System.ComponentModel.ISupportInitialize)(this.trackBarX)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.trackBarY)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        private void trackBar_Scroll(object sender, EventArgs e)
        {
            selectedPosition = new Point(trackBarX.Value, trackBarY.Value);
            UpdatePositionLabels();
        }

        private void UpdatePositionLabels()
        {
            labelValueX.Text = $"{trackBarX.Value}px";
            labelValueY.Text = $"{trackBarY.Value}px";
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }
    }
}

SplitForm.cs

cs 复制代码
using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace PDFTools
{
    public partial class SplitForm : Form
    {
        private string selectedFilePath = "";

        public SplitForm()
        {
            InitializeComponent();
        }

        private void btnSelectFile_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.Filter = "PDF文件|*.pdf";
                openFileDialog.Title = "选择要切割的PDF文件";

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    selectedFilePath = openFileDialog.FileName;
                    lblFileName.Text = "已选择: " + System.IO.Path.GetFileName(selectedFilePath);
                    
                    try
                    {
                        using (PdfReader reader = new PdfReader(selectedFilePath))
                        {
                            int totalPages = reader.NumberOfPages;
                            lblPageInfo.Text = "总页数: " + totalPages;
                            lblTotalPages.Text = totalPages.ToString();
                            
                            // 设置结束页的默认值
                            txtEndPage.Text = totalPages.ToString();
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("读取PDF文件失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }

        private void rbSinglePage_CheckedChanged(object sender, EventArgs e)
        {
            txtPagesPerFile.Enabled = false;
            txtStartPage.Enabled = false;
            txtEndPage.Enabled = false;
        }

        private void rbMultiPage_CheckedChanged(object sender, EventArgs e)
        {
            txtPagesPerFile.Enabled = rbMultiPage.Checked;
            txtStartPage.Enabled = false;
            txtEndPage.Enabled = false;
        }

        private void rbPageRange_CheckedChanged(object sender, EventArgs e)
        {
            txtPagesPerFile.Enabled = false;
            txtStartPage.Enabled = rbPageRange.Checked;
            txtEndPage.Enabled = rbPageRange.Checked;
        }

        private void btnSplit_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(selectedFilePath))
            {
                MessageBox.Show("请先选择PDF文件", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            if (!File.Exists(selectedFilePath))
            {
                MessageBox.Show("选择的文件不存在", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            using (FolderBrowserDialog folderDialog = new FolderBrowserDialog())
            {
                folderDialog.Description = "选择输出文件夹";
                if (folderDialog.ShowDialog() == DialogResult.OK)
                {
                    string outputFolder = folderDialog.SelectedPath;

                    try
                    {
                        if (rbSinglePage.Checked)
                        {
                            SplitIntoSinglePages(selectedFilePath, outputFolder);
                        }
                        else if (rbMultiPage.Checked)
                        {
                            if (!int.TryParse(txtPagesPerFile.Text, out int pagesPerFile) || pagesPerFile < 1)
                            {
                                MessageBox.Show("请输入有效的每份页数", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                return;
                            }
                            SplitIntoMultiPages(selectedFilePath, outputFolder, pagesPerFile);
                        }
                        else if (rbPageRange.Checked)
                        {
                            if (!int.TryParse(txtStartPage.Text, out int startPage) || 
                                !int.TryParse(txtEndPage.Text, out int endPage) || 
                                startPage < 1 || endPage < startPage)
                            {
                                MessageBox.Show("请输入有效的页面范围", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                return;
                            }
                            
                            // 检查结束页是否超过总页数
                            int totalPages = int.Parse(lblTotalPages.Text);
                            if (endPage > totalPages)
                            {
                                MessageBox.Show($"结束页不能超过总页数 {totalPages}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                return;
                            }
                            
                            SplitPageRange(selectedFilePath, outputFolder, startPage, endPage);
                        }

                        MessageBox.Show("PDF切割完成!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("切割失败: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }

        private void SplitIntoSinglePages(string inputFile, string outputFolder)
        {
            using (PdfReader reader = new PdfReader(inputFile))
            {
                int totalPages = reader.NumberOfPages;

                for (int i = 1; i <= totalPages; i++)
                {
                    string outputFile = System.IO.Path.Combine(outputFolder, $"page_{i.ToString().PadLeft(4, '0')}.pdf");

                    using (Document document = new Document())
                    using (FileStream fs = new FileStream(outputFile, FileMode.Create))
                    using (PdfCopy copy = new PdfCopy(document, fs))
                    {
                        document.Open();
                        copy.AddPage(copy.GetImportedPage(reader, i));
                        document.Close();
                    }
                }
            }
        }

        private void SplitIntoMultiPages(string inputFile, string outputFolder, int pagesPerFile)
        {
            using (PdfReader reader = new PdfReader(inputFile))
            {
                int totalPages = reader.NumberOfPages;
                int fileCount = (int)Math.Ceiling((double)totalPages / pagesPerFile);

                for (int fileIndex = 0; fileIndex < fileCount; fileIndex++)
                {
                    int startPage = fileIndex * pagesPerFile + 1;
                    int endPage = Math.Min((fileIndex + 1) * pagesPerFile, totalPages);

                    string outputFile = System.IO.Path.Combine(outputFolder, $"part_{(fileIndex + 1).ToString().PadLeft(3, '0')}_pages_{startPage}-{endPage}.pdf");

                    using (Document document = new Document())
                    using (FileStream fs = new FileStream(outputFile, FileMode.Create))
                    using (PdfCopy copy = new PdfCopy(document, fs))
                    {
                        document.Open();

                        for (int page = startPage; page <= endPage; page++)
                        {
                            copy.AddPage(copy.GetImportedPage(reader, page));
                        }

                        document.Close();
                    }
                }
            }
        }

        private void SplitPageRange(string inputFile, string outputFolder, int startPage, int endPage)
        {
            using (PdfReader reader = new PdfReader(inputFile))
            {
                int totalPages = reader.NumberOfPages;
                
                // 验证页面范围
                if (startPage < 1 || endPage > totalPages || startPage > endPage)
                {
                    MessageBox.Show("无效的页面范围", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                string outputFile = System.IO.Path.Combine(outputFolder, 
                    $"pages_{startPage}-{endPage}_{System.IO.Path.GetFileNameWithoutExtension(inputFile)}.pdf");

                using (Document document = new Document())
                using (FileStream fs = new FileStream(outputFile, FileMode.Create))
                using (PdfCopy copy = new PdfCopy(document, fs))
                {
                    document.Open();

                    for (int page = startPage; page <= endPage; page++)
                    {
                        copy.AddPage(copy.GetImportedPage(reader, page));
                    }

                    document.Close();
                }
                
                // 如果只切割一页,也创建一个单页文件
                if (startPage == endPage)
                {
                    string singlePageFile = System.IO.Path.Combine(outputFolder, 
                        $"page_{startPage.ToString().PadLeft(4, '0')}.pdf");
                    
                    using (Document document = new Document())
                    using (FileStream fs = new FileStream(singlePageFile, FileMode.Create))
                    using (PdfCopy copy = new PdfCopy(document, fs))
                    {
                        document.Open();
                        copy.AddPage(copy.GetImportedPage(reader, startPage));
                        document.Close();
                    }
                }
            }
        }
    }
}

SplitForm.Designer.cs

cs 复制代码
namespace PDFTools
{
    partial class SplitForm
    {
        private System.ComponentModel.IContainer components = null;

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        private void InitializeComponent()
        {
            this.lblFileName = new System.Windows.Forms.Label();
            this.btnSelectFile = new System.Windows.Forms.Button();
            this.lblPageInfo = new System.Windows.Forms.Label();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.rbPageRange = new System.Windows.Forms.RadioButton();
            this.rbMultiPage = new System.Windows.Forms.RadioButton();
            this.rbSinglePage = new System.Windows.Forms.RadioButton();
            this.txtPagesPerFile = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.txtStartPage = new System.Windows.Forms.TextBox();
            this.txtEndPage = new System.Windows.Forms.TextBox();
            this.label2 = new System.Windows.Forms.Label();
            this.label3 = new System.Windows.Forms.Label();
            this.btnSplit = new System.Windows.Forms.Button();
            this.lblTotalPages = new System.Windows.Forms.Label();
            this.groupBox1.SuspendLayout();
            this.SuspendLayout();
            
            // lblFileName
            this.lblFileName.AutoSize = true;
            this.lblFileName.Location = new System.Drawing.Point(120, 25);
            this.lblFileName.Name = "lblFileName";
            this.lblFileName.Size = new System.Drawing.Size(77, 12);
            this.lblFileName.TabIndex = 0;
            this.lblFileName.Text = "未选择文件";
            
            // btnSelectFile
            this.btnSelectFile.Location = new System.Drawing.Point(20, 20);
            this.btnSelectFile.Name = "btnSelectFile";
            this.btnSelectFile.Size = new System.Drawing.Size(90, 25);
            this.btnSelectFile.TabIndex = 1;
            this.btnSelectFile.Text = "选择PDF文件";
            this.btnSelectFile.Click += new System.EventHandler(this.btnSelectFile_Click);
            
            // lblPageInfo
            this.lblPageInfo.AutoSize = true;
            this.lblPageInfo.Location = new System.Drawing.Point(20, 60);
            this.lblPageInfo.Name = "lblPageInfo";
            this.lblPageInfo.Size = new System.Drawing.Size(59, 12);
            this.lblPageInfo.TabIndex = 2;
            this.lblPageInfo.Text = "总页数: 0";
            
            // groupBox1
            this.groupBox1.Controls.Add(this.rbPageRange);
            this.groupBox1.Controls.Add(this.rbMultiPage);
            this.groupBox1.Controls.Add(this.rbSinglePage);
            this.groupBox1.Location = new System.Drawing.Point(20, 90);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(350, 100);
            this.groupBox1.TabIndex = 3;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "切割方式";
            
            // rbPageRange
            this.rbPageRange.AutoSize = true;
            this.rbPageRange.Location = new System.Drawing.Point(20, 70);
            this.rbPageRange.Name = "rbPageRange";
            this.rbPageRange.Size = new System.Drawing.Size(95, 16);
            this.rbPageRange.TabIndex = 2;
            this.rbPageRange.Text = "指定页面范围";
            this.rbPageRange.CheckedChanged += new System.EventHandler(this.rbPageRange_CheckedChanged);
            
            // rbMultiPage
            this.rbMultiPage.AutoSize = true;
            this.rbMultiPage.Location = new System.Drawing.Point(20, 45);
            this.rbMultiPage.Name = "rbMultiPage";
            this.rbMultiPage.Size = new System.Drawing.Size(71, 16);
            this.rbMultiPage.TabIndex = 1;
            this.rbMultiPage.Text = "多页切割";
            this.rbMultiPage.CheckedChanged += new System.EventHandler(this.rbMultiPage_CheckedChanged);
            
            // rbSinglePage
            this.rbSinglePage.AutoSize = true;
            this.rbSinglePage.Checked = true;
            this.rbSinglePage.Location = new System.Drawing.Point(20, 20);
            this.rbSinglePage.Name = "rbSinglePage";
            this.rbSinglePage.Size = new System.Drawing.Size(71, 16);
            this.rbSinglePage.TabIndex = 0;
            this.rbSinglePage.TabStop = true;
            this.rbSinglePage.Text = "单页切割";
            this.rbSinglePage.CheckedChanged += new System.EventHandler(this.rbSinglePage_CheckedChanged);
            
            // txtPagesPerFile
            this.txtPagesPerFile.Enabled = false;
            this.txtPagesPerFile.Location = new System.Drawing.Point(120, 200);
            this.txtPagesPerFile.Name = "txtPagesPerFile";
            this.txtPagesPerFile.Size = new System.Drawing.Size(60, 21);
            this.txtPagesPerFile.TabIndex = 4;
            this.txtPagesPerFile.Text = "10";
            
            // label1
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(25, 203);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(89, 12);
            this.label1.TabIndex = 5;
            this.label1.Text = "每份文件页数:";
            
            // txtStartPage
            this.txtStartPage.Enabled = false;
            this.txtStartPage.Location = new System.Drawing.Point(120, 230);
            this.txtStartPage.Name = "txtStartPage";
            this.txtStartPage.Size = new System.Drawing.Size(60, 21);
            this.txtStartPage.TabIndex = 6;
            this.txtStartPage.Text = "1";
            
            // txtEndPage
            this.txtEndPage.Enabled = false;
            this.txtEndPage.Location = new System.Drawing.Point(220, 230);
            this.txtEndPage.Name = "txtEndPage";
            this.txtEndPage.Size = new System.Drawing.Size(60, 21);
            this.txtEndPage.TabIndex = 7;
            this.txtEndPage.Text = "1";
            
            // label2
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(25, 233);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(89, 12);
            this.label2.TabIndex = 8;
            this.label2.Text = "起始页-结束页:";
            
            // label3
            this.label3.AutoSize = true;
            this.label3.Location = new System.Drawing.Point(190, 233);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(23, 12);
            this.label3.TabIndex = 9;
            this.label3.Text = "到";
            
            // btnSplit
            this.btnSplit.Location = new System.Drawing.Point(150, 270);
            this.btnSplit.Name = "btnSplit";
            this.btnSplit.Size = new System.Drawing.Size(100, 30);
            this.btnSplit.TabIndex = 10;
            this.btnSplit.Text = "开始切割";
            this.btnSplit.Click += new System.EventHandler(this.btnSplit_Click);
            
            // lblTotalPages
            this.lblTotalPages.AutoSize = true;
            this.lblTotalPages.Location = new System.Drawing.Point(120, 60);
            this.lblTotalPages.Name = "lblTotalPages";
            this.lblTotalPages.Size = new System.Drawing.Size(11, 12);
            this.lblTotalPages.TabIndex = 11;
            this.lblTotalPages.Text = "0";
            
            // SplitForm
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(400, 320);
            this.Controls.Add(this.lblTotalPages);
            this.Controls.Add(this.btnSplit);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.txtEndPage);
            this.Controls.Add(this.txtStartPage);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.txtPagesPerFile);
            this.Controls.Add(this.groupBox1);
            this.Controls.Add(this.lblPageInfo);
            this.Controls.Add(this.btnSelectFile);
            this.Controls.Add(this.lblFileName);
            this.Name = "SplitForm";
            this.Text = "PDF切割";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.groupBox1.ResumeLayout(false);
            this.groupBox1.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        #endregion

        private System.Windows.Forms.Label lblFileName;
        private System.Windows.Forms.Button btnSelectFile;
        private System.Windows.Forms.Label lblPageInfo;
        private System.Windows.Forms.GroupBox groupBox1;
        private System.Windows.Forms.RadioButton rbPageRange;
        private System.Windows.Forms.RadioButton rbMultiPage;
        private System.Windows.Forms.RadioButton rbSinglePage;
        private System.Windows.Forms.TextBox txtPagesPerFile;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.TextBox txtStartPage;
        private System.Windows.Forms.TextBox txtEndPage;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Label label3;
        private System.Windows.Forms.Button btnSplit;
        private System.Windows.Forms.Label lblTotalPages;
    }
}
相关推荐
熙客3 分钟前
Java:LinkedList的使用
java·开发语言
大飞pkz1 小时前
【Lua】题目小练12
开发语言·lua·题目小练
赵得C1 小时前
Java 多线程环境下的全局变量缓存实践指南
java·开发语言·后端·spring·缓存
nightunderblackcat2 小时前
新手向:Python编写简易翻译工具
开发语言·python
EndingCoder2 小时前
Electron 简介:Node.js 桌面开发的起点
开发语言·前端·javascript·electron·node.js·桌面端
m0_480502642 小时前
Rust 登堂 之 类型转换(三)
开发语言·后端·rust
郏国上3 小时前
如何循环同步下载文件
开发语言·javascript·node.js