WinForm中实现Adobe PDF Reader实现旋转PDF功能

实现效果:

WinForm中实现Adobe PDF Reader实现旋转PDF功能

问题点:Adobe PDF Reader中并没有可以直接旋转的方法

LoadFile 加载文件,文件URL地址
GotoFirstPage 到第一页
GotoLastPage 到最后一页
GotoPreviousPage 上一页
GotoNextPape 下一页
SetCurrentpage 到指定页
Setshowscrollbars 设置是否显示 Acrobat Reader的滚动条。带一个参数,该参数设为0时不显示滚动条,设为1时显示滚动条
SetshowToolbar 设置是否显示 Acrobat Reader的工具栏。带一个参数,该参数设为时不显示,设为1时显示。
Setview 设置显示效果。Fit:适应窗口大小; FitH:适合宽度
setZoom 设置文件的显示比例;默认是100

解决办法:引入PdfiumViewer旋转PDF并保存替换当前的文件。

		 /// <summary>         /// 旋转保存PDF文件并释放文件锁定         /// </summary>         /// <param name="axControl"></param>         /// <param name="filePath"></param>         /// <param name="pdfRotation"></param>         /// <returns></returns>     public bool SafeSavePdfWithRelease(AxAcroPDFLib.AxAcroPDF axControl, string filePath, PdfRotation pdfRotation)     {         const int MAX_RETRY = 3;         const int RETRY_DELAY = 500;          for (int attempt = 0; attempt < MAX_RETRY; attempt++)         {             try             {                 // 步骤1:创建临时副本                 string tempPath = Path.GetTempFileName().Replace(".tmp", ".pdf");                 File.Copy(filePath, tempPath, true);                  // 步骤2:使用内存流操作                 using (var ms = new MemoryStream(File.ReadAllBytes(tempPath)))                 using (var document = PdfiumViewer.PdfDocument.Load(ms))                 {                     for (int pageIndex = 0; pageIndex < document.PageCount; pageIndex++)                     {                         document.RotatePage(pageIndex, pdfRotation);                          // 可选:验证旋转结果                         // var currentRotation = document.Pages[pageIndex].Rotation;                         // Debug.Assert(currentRotation == (int)rotation);                     }                     // 执行修改操作(示例:旋转第一页)                     //document.RotatePage(1, PdfRotation.Rotate90);                      // 步骤3:保存到临时文件                     byte[] pdfBytes;                     using (var outputStream = new MemoryStream())                     {                         document.Save(outputStream);                         pdfBytes = outputStream.ToArray();                     }                      // 步骤4:强制释放文件锁定                     ForceReleasePdfFile(axControl, filePath);                      // 步骤5:原子替换文件                     File.WriteAllBytes(tempPath, pdfBytes);                     // File.Replace(tempPath, filePath, null, true);                      // 1. 复制替换文件到目标路径                     File.Copy(tempPath, filePath, overwrite: true);                      // 2. 删除临时文件(可选)                     File.Delete(tempPath);                      // 步骤6:验证加载                     axControl.LoadFile(filePath);                     return true;                 }             }             catch (IOException ex) when (ex.HResult == -2147024864)             {                 if (attempt == MAX_RETRY - 1) throw;                 Thread.Sleep(RETRY_DELAY);             }         }         return false;     }     public void ForceReleasePdfFile(AxAcroPDFLib.AxAcroPDF axControl, string filePath)     {         // 步骤1:深度释放COM对象         ReleaseComObject(axControl);          // 步骤2:内核级文件解锁         UnlockFileHandle(filePath);          // 步骤3:延迟重载验证         Thread.Sleep(200);         axControl.LoadFile(filePath);     }      private void ReleaseComObject(AxAcroPDFLib.AxAcroPDF axControl)     {         try         {             // 显式释放ActiveX资源             if (axControl.IsDisposed) return;              // 反射调用内部释放方法             var type = axControl.GetType();             var method = type.GetMethod("ReleaseOCX", BindingFlags.Instance | BindingFlags.NonPublic);             method?.Invoke(axControl, null);              // 强制垃圾回收             GC.Collect();             GC.WaitForPendingFinalizers();         }         catch (Exception ex)         {          }     }     // 修改后的P/Invoke声明     [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]     private static extern IntPtr CreateFile(         string lpFileName,         uint dwDesiredAccess,         uint dwShareMode,         IntPtr lpSecurityAttributes,         FileMode dwCreationDisposition,  // 改用.NET枚举         FileAttributes dwFlagsAndAttributes,  // 改用.NET枚举         IntPtr hTemplateFile);      // 修改后的UnlockFileHandle方法     private void UnlockFileHandle(string filePath)     {         const uint FILE_SHARE_READ = 0x00000001;         const uint FILE_SHARE_WRITE = 0x00000002;         const uint GENERIC_READ = 0x80000000;          IntPtr hFile = CreateFile(             filePath,             GENERIC_READ,             FILE_SHARE_READ | FILE_SHARE_WRITE,             IntPtr.Zero,             FileMode.Open,  // 对应原生OPEN_EXISTING             FileAttributes.Normal,  // 对应原生FILE_ATTRIBUTE_NORMAL             IntPtr.Zero);          if (hFile != IntPtr.Zero && hFile != new IntPtr(-1))         {             CloseHandle(hFile);         }     }      [DllImport("kernel32.dll", SetLastError = true)]     [return: MarshalAs(UnmanagedType.Bool)]     private static extern bool CloseHandle(IntPtr hObject);` 

调用代码:

		  /// <summary>         /// 当前旋转角度         /// </summary>         public static int currentRotation = 0;          /// <summary>         /// 逆时针旋转         /// </summary>         /// <param name="sender"></param>         /// <param name="e"></param>         private void pictureEdit3_Click(object sender, EventArgs e)         {             if (axAcroPDF1.Visible)             {                 currentRotation -= 90;                   PdfRotation pdfRotation = GetCounterClockwiseRotation(currentRotation);                                   var path = axAcroPDF1.src;                 //调用旋转PDF保存方法                 SafeSavePdfWithRelease(axAcroPDF1, path,pdfRotation);                  axAcroPDF1.LoadFile(path);                 axAcroPDF1.setView("Fit"); //适应窗口大小             }         }          /// <summary>         /// 顺时针旋转         /// </summary>         /// <param name="sender"></param>         /// <param name="e"></param>         private void pictureEdit2_Click(object sender, EventArgs e)         {             if (axAcroPDF1.Visible)             {                 currentRotation += 90;                   PdfRotation pdfRotation = GetCounterClockwiseRotation(currentRotation);                  var path = axAcroPDF1.src;                 //调用旋转PDF保存方法                 SafeSavePdfWithRelease(axAcroPDF1, path, pdfRotation);                  axAcroPDF1.LoadFile(path);                 axAcroPDF1.setView("Fit"); //适应窗口大小              }         }           /// <summary>         /// 通过旋转度数计算旋转的角度         /// </summary>         /// <param name="counterClockwiseDegrees">当前旋转角度</param>         public static PdfRotation GetCounterClockwiseRotation(int counterClockwiseDegrees)         {             const int fullCircle = 360;             int effectiveDegrees = counterClockwiseDegrees % fullCircle;              if (effectiveDegrees < 0) effectiveDegrees += fullCircle; // 处理负角度              if (currentRotation >= 360)              {                 currentRotation = 0;             }             if (currentRotation <= -360)              {                 currentRotation = 0;             }              switch (effectiveDegrees)             {                 case 90:                     return PdfRotation.Rotate90;                  case 180:                     return PdfRotation.Rotate180;                 case 270:                     return PdfRotation.Rotate270;                 case 0:                 default:                     return PdfRotation.Rotate0;             }         }         /// <summary> 

发表评论

评论已关闭。

相关文章