实现效果:

问题点: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. Laravel 配置连接多个数据库以及如何使用

    目录 配置连接 配置 .env 文件 配置 \config\database.php 文件 使用 Schema Query Eloquent 配置连接 配置 .env 文件 /* 这部分是默认的数据库 ...

  2. Tomcat的优化(分别为操作系统优化(内核参数优化),Tomcat配置文件参数优化,Java虚拟机(JVM)调优)

    Tomcat的优化        一.Tomcat 优化                Tomcat 配置文件参数优化        二.系统内核优化        三.Tomcat 配置 JVM 参 ...

  3. bug|electron-vue 使用 electron-builder 打包,执行 yarn run build 报错原因

    问题 & 解决 官方BUG:tasks 重复: yarn run build yarn run v1.22.22 $ node .electron-vue/build.js && ...

  4. 智能Agent如何改造传统工作流:从搜索到全能助手

    智能Agent如何改造传统工作流:从搜索到全能助手 引言:当AI遇上工作流 还记得我们以前搜索信息的方式吗?输入关键词,浏览大量结果,筛选有用内容,再整合成我们需要的答案.这个过程不仅耗时,还常常让人 ...

  5. 《机器人SLAM导航核心技术与实战》第1季:第1章_ROS入门必备知识

    <机器人SLAM导航核心技术与实战>第1季:第1章_ROS入门必备知识 视频讲解 [第1季]1.第1章_ROS入门必备知识-视频讲解 [第1季]1.1.第1章_ROS入门必备知识-ROS简 ...

  6. DRG,医改分水岭!

    2020-11-04 (2021年政府推出2.0版DRG.增加MCC和CC,各自政府的医保支付中增加了人性化的支付倍率的处理) 假设某疾病病组支付标准10000元,患者自付自费比例40%,分三种情况, ...

  7. FireDAC开发DataSnap应用系统【2】-使用TFDJSONDatasets功能

    类别 说明 TFDJSONDatasets FireDAC使用JSONDataSet,其中可包括多个DataSet对象 TFDJSONDataSetsWriter 把TDataSet写入TFDJSON ...

  8. ArrayBlockingQueue的poll方法底层原理

    一.ArrayBlockingQueue的poll方法底层原理 ArrayBlockingQueue 是 Java 并发包 (java.util.concurrent) 中的一个基于数组实现的有界阻塞 ...

  9. 需要的效果它都有,让AI对话开发效率翻倍!这款Ant Design扩展组件库绝了

    嗨,大家好,我是小华同学,关注我们获得"最新.最全.最优质"开源项目和高效工作学习方法 ant-design-x-vue 是基于 Ant Design Vue 的扩展组件库,专注于 ...

  10. cloudflare xss绕过未修复