You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure PowerShell Runbook中iText7修改PDF后无法保存至SharePoint

解决方案:Azure Runbook中修改PDF并保存至SharePoint Online

方案一:修复iText7修改后的PDF保存流程

你当前的问题大概率是修改后未重置MemoryStream的位置,导致写入SPO时流为空。以下是完整的可行流程:

关键操作点

  • 修改PDF后,必须将输出MemoryStream的Position重置为0,否则写入会从流的末尾开始,生成空白文件。
  • 使用PnP PowerShell的Add-PnPFile命令完成流到SPO的写入,这是Azure Runbook中操作SPO文件最稳定的方式。

完整代码示例

# 安装/导入PnP模块(Runbook首次运行需执行,可重复执行)
if (-not (Get-Module -Name PnP.PowerShell -ListAvailable)) {
    Install-Module -Name PnP.PowerShell -Force -AllowClobber -Scope CurrentUser
}
Import-Module PnP.PowerShell

# 连接SharePoint Online(示例用应用身份验证,也可替换为托管身份)
$siteUrl = "https://yourtenant.sharepoint.com/sites/yoursite"
$clientId = "你的应用客户端ID"
$clientSecret = ConvertTo-SecureString "你的应用客户端密钥" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($clientId, $clientSecret)
Connect-PnPOnline -Url $siteUrl -Credentials $cred

# 读取源PDF到MemoryStream
$sourceFilePath = "/sites/yoursite/Shared Documents/SourceFolder/原始文件.pdf"
$sourceFile = Get-PnPFile -Url $sourceFilePath -AsFileObject
$sourceStream = New-Object System.IO.MemoryStream
$sourceFile.OpenBinaryStream().Result.CopyTo($sourceStream)

# 用iText7修改PDF(替换为你的现有修改逻辑)
Add-Type -Path "$env:TEMP/itext.kernel.dll"
Add-Type -Path "$env:TEMP/itext.layout.dll"

$reader = New-Object iText.Kernel.Pdf.PdfReader($sourceStream)
$outputStream = New-Object System.IO.MemoryStream
$writer = New-Object iText.Kernel.Pdf.PdfWriter($outputStream)
$pdfDoc = New-Object iText.Kernel.Pdf.PdfDocument($reader, $writer)

# 示例:添加空白页(替换成你的修改代码)
$pdfDoc.AddNewPage()

# 关闭文档,确保内容写入输出流
$pdfDoc.Close()
$reader.Close()
$writer.Close()

# 重置输出流位置到开头(核心步骤!)
$outputStream.Position = 0

# 保存到目标SPO文件夹
$targetFolderPath = "/sites/yoursite/Shared Documents/TargetFolder"
Add-PnPFile -FileName "修改后的文件.pdf" -Folder $targetFolderPath -Stream $outputStream

# 清理资源
$sourceStream.Dispose()
$outputStream.Dispose()
Disconnect-PnPOnline

注意事项

  • 将iText7的DLL文件(itext.kernel.dll、itext.layout.dll)上传至Azure Automation资产库,或在Runbook中下载到临时目录$env:TEMP。
  • 若使用托管身份连接SPO,只需将连接命令改为Connect-PnPOnline -Url $siteUrl -ManagedIdentity,并确保托管身份拥有SPO站点的编辑权限。

方案二:纯PowerShell替代方案(使用PdfSharp)

如果不想依赖iText7,可使用开源.NET库PdfSharp,直接在PowerShell中实现PDF修改:

代码示例

# 安装/导入PnP模块(同方案一)
if (-not (Get-Module -Name PnP.PowerShell -ListAvailable)) {
    Install-Module -Name PnP.PowerShell -Force -AllowClobber -Scope CurrentUser
}
Import-Module PnP.PowerShell

# 连接SPO
$siteUrl = "https://yourtenant.sharepoint.com/sites/yoursite"
$clientId = "你的应用客户端ID"
$clientSecret = ConvertTo-SecureString "你的应用客户端密钥" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($clientId, $clientSecret)
Connect-PnPOnline -Url $siteUrl -Credentials $cred

# 读取源PDF到MemoryStream
$sourceFilePath = "/sites/yoursite/Shared Documents/SourceFolder/原始文件.pdf"
$sourceFile = Get-PnPFile -Url $sourceFilePath -AsFileObject
$sourceStream = New-Object System.IO.MemoryStream
$sourceFile.OpenBinaryStream().Result.CopyTo($sourceStream)
$sourceStream.Position = 0

# 引用PdfSharp DLL(需提前上传到Runbook资产库)
Add-Type -Path "$env:TEMP/PdfSharp.dll"
Add-Type -Path "$env:TEMP/PdfSharp.Drawing.dll"

# 修改PDF(示例添加空白页)
$pdfDoc = PdfSharp.Pdf.IO.PdfReader.Open($sourceStream, PdfSharp.Pdf.IO.PdfDocumentOpenMode.Modify)
$pdfDoc.AddPage()

# 写入输出流
$outputStream = New-Object System.IO.MemoryStream
$pdfDoc.Save($outputStream)
$pdfDoc.Close()

# 重置流位置并保存到SPO
$outputStream.Position = 0
$targetFolderPath = "/sites/yoursite/Shared Documents/TargetFolder"
Add-PnPFile -FileName "修改后的文件_ps.pdf" -Folder $targetFolderPath -Stream $outputStream

# 清理资源
$sourceStream.Dispose()
$outputStream.Dispose()
Disconnect-PnPOnline

注意事项

  • PdfSharp对复杂PDF的支持不如iText7,适合简单的页面添加、合并等操作;若需高级编辑(如文本替换、表单处理),建议优先用方案一。

内容的提问来源于stack exchange,提问作者Marc Codere Dussault

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 14:10:26