实现效果:

问题点: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>

WinForms中实现Adobe PDF Reader实现旋转PDF功能的更多相关文章

  1. PDF怎么编辑,如何旋转PDF页面方向

    很多的时候,无论是工作中,还是在学习中都会遇到PDF文件,对于PDF文件,熟悉的小伙伴知道,在编辑PDF文件的时候,是需要使用到PDF编辑软件的,那么,在编辑PDF文件的时候,需要旋转文件的页面,这时 ...

  2. Adobe Acrobat Reader DC 离线安装包

    https://blog.csdn.net/qqduxingzhe/article/details/77876336 ************************************* win ...

  3. 怎样用Adobe Acrobat 7 Pro把PDF文档拆分成多个啊?

    这个pdf文档里有多篇文章,我想把他们分开并分别保存在独立的pdf文档.怎么操作?我的电脑基础不太好,麻烦说得详细一些. Adobe Acrobat 7 Pro拆分PDF文档的方法: 1.点左边的“书 ...

  4. 使用Adobe Arcobat Pro DC生成PDF提示“PDFMaker文件遗失”新解决思路

    环境: 1.Window 7 2.Adobe Arcobat Pro DC 2020.009.20065 3.Microsoft Office 2007 4.WPS 2019 虽然可以使用插件实现文件 ...

  5. python实现PDF指定页面旋转

    下面示例代码,是将横向纸张旋转为纵向(根据纸张大小判断纸张方向) 方法一:使用PyPDF2库 from PyPDF2 import PdfFileWriter, PdfFileReader def p ...

  6. 如何使用免费PDF控件从PDF文档中提取文本和图片

             如何使用免费PDF控件从PDF文档中提取文本和图片 概要 现在手头的项目有一个需求是从PDF文档中提取文本和图片,我以前也使用过像iTextSharp, PDFBox 这些免费的PD ...

  7. 将Altium中的原理图与PCB导出为PDF的步骤与方法

    1.通过File-Smart PDF(文件-智能PDF),快捷键F-M打开. 2.选择打印的范围:Current Project还是Current Document,还有生成的PDF的存放位置. 3. ...

  8. Foxit Reader(福昕PDF阅读器) v4.3.1.218 绿色专业版

    软件名称:Foxit Reader(福昕PDF阅读器) v4.3.1.218 绿色专业版 软件语言: 简体中文 授权方式: 免费软件 运行环境: Win 32位/64位 软件大小: 4.40MB 图片 ...

  9. PDF中的空白页面怎么删除,PDF页面删除技巧

    在Word中想要删除其中一页文档的怎么办?直接打开就可以删除了,那么我们如何删除PDF其中几页呢?下面小编就来告诉大家PDF删除页面跟空白页面的方法.想要删除PDF文档中的页面,可以使用PDF编辑器, ...

  10. 官网下载到离线的Adobe Acrobat Reader DC

    Adobe 官方 FTP :ftp://ftp.adobe.com/ Adobe Acrobat Reader DC 下载目录:ftp://ftp.adobe.com/pub/adobe/reader ...

随机推荐

  1. mac环境配置本地nfs服务

    前言 在这篇文章中,讲了在Mac端开启NFS服务,并通过NFS协议让其他设备挂载到你的Mac上. 步骤一:增加配置文件 首先,我们需要编辑NFS的配置文件,以便定义哪些目录可以被远程访问. 打开终端, ...

  2. Ubuntu22.04 搭建Kubernetes 1.28版本集群

    依赖安装 准备工作需要在所有节点上进行. 安装 ssh 服务 安装 openssh-server sudo apt-get install openssh-server 修改配置文件 vim /etc ...

  3. 解决Linux下文本文件中文乱码问题

    上一篇我们提到了OS和DB的一些中文乱码问题解决,本篇我们继续介绍下在OS上的文本文件中文乱码问题. 操作系统是Linux(OEL 8.10),所有文件是打了一个压缩包上传的,上传解压后发现其中的文本 ...

  4. 学习unigui【23】uniDBGrid的使用摘要

    Unidbgrid自动调整列宽 UniDBGrid1 -> ClientEvents -> ExtEvents [Ext.data.Store[store] ] add store.loa ...

  5. 详细介绍Mybatis的缓存机制

    一.缓存机制 1.缓存概述 缓存:缓存就是一块内存空间,保存临时数据 作用:将数据源(数据库或者文件)中的数据读取出来存放到缓存中,再次获取时直接从缓存中获取,可以减少和数据库交互的次数,提升程序的性 ...

  6. 如何应对ADAS/AD海量数据处理挑战?

    随着软件定义汽车的发展,车辆生成的数据量也以前所未有的速度不断增加.这些数据包含广泛的信息,包括传感器数据.遥测数据.诊断数据等.在开发过程中,有效处理这些数据并从中获得见解至关重要. 对于原始设备制 ...

  7. 2024dsfzB层考试总结

    2024B层次十一集训 10.3日 数据结构专题模拟 考试总结 FrankWKD Updated AT 2024/10/3 13:21 概述 总分:\(140/400\) Rank:\(24/87\) ...

  8. 微信小程序 6/12 的坑

    配置 小程序的时候配置请求的是 https://xxx 不是http://xxx 前端请求的链接都是https

  9. 俩天完美复刻DeepWiki,并且免费开源!

    俩天完美复刻DeepWiki,并且免费开源! 大家好!今天非常高兴为大家介绍KoalaWiki项目 - 这是我们团队花费两天时间完美复刻一个免费开源的AI驱动代码知识库系统,可以说是DeepWiki的 ...

  10. MIUI系统,APKMirror Installer安装apkm的时候提示app installation failed Installation aborted解决方案

    场景 我的手机是MIUI系统,通过APKMirror Installer安装apkm的时候提示app installation failed Installation aborted. 本来不想装了, ...