.Net5 WebApi中操作PDF(分割复制PDF指定页 and 合并多个PDF文件)
安装Nuget包
.Net Framework:install-package iTextSharp
.Net Core/.Net5:install-package iTextSharp.LGPLv2.Core(我安装的1.7.1)
PDF工具类 and 合并多个PDF为一个PDF
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Levox.Framework.Core.CommonUtils;
using Levox.Framework.Core.Extensions;
using Levox.Framework.Core.Models.Exceptions;
using Levox.Framework.Core.Models.File;
namespace Levox.Framework.Core.Pdfs
{
public class PdfUtil
{
/// <summary>
/// 复制目标PDF文件的指定页内容,生成一个新的PDF文件 LastUpdateDate:2021-06-29 14:36:33.875 Author:Lingbug
/// </summary>
/// <param name="outputPdfFileName">新PDF文件名(自动识别是否带有.pdf后缀),为空默认为OutputSplitPdfFileName</param>
/// <param name="sourcePdfPath">目标PDF文件在系统内的相对路径</param>
/// <param name="pageNumbers">要复制的页集合,从1开始</param>
/// <returns>新的PDF文件相对路径</returns>
public static string CreatePdfByCustomPages(string outputPdfFileName, string sourcePdfPath, IEnumerable<int> pageNumbers)
{
//校验
if (sourcePdfPath.IsNullOrWhiteSpaceString()) throw new ErpFriendlyException("要分割复制的PDF源文件路径不能为空!");
//校验
if (pageNumbers.IsNullOrEmptyList()) throw new ErpFriendlyException("要复制的PDF页码集合不能为空!");
//去重排序
pageNumbers = pageNumbers.Distinct().OrderBy(r => r);
//校验
if (pageNumbers.First() <= 0) throw new ErpFriendlyException("要复制的PDF页码必须大于0!");
//完整路径
string sourcePdfFullPath = FileUtil.GetFullPath(sourcePdfPath);
//校验
if (!File.Exists(sourcePdfFullPath)) throw new ErpFriendlyException("要复制分割的PDF源文件不存在!");
//读取源文件
var reader = new PdfReader(sourcePdfFullPath);
//校验
if (pageNumbers.Last() > reader.NumberOfPages) throw new ErpFriendlyException($"要复制的PDF页码必须小于等于源文件总页数【{reader.NumberOfPages}】!");
//结果文件
var fileOutput = GetOutputPdfFileInfo(outputPdfFileName, "OutputSplitPdfFileName");
//初始化
var sourceDocument = new Document(reader.GetPageSizeWithRotation(pageNumbers.First()));
//初始化
var pdfCopyProvider = new PdfCopy(sourceDocument, new FileStream(fileOutput.FileFullPath, FileMode.Create));
//打开
sourceDocument.Open();
//复制指定页
foreach (var pageNumber in pageNumbers) pdfCopyProvider.AddPage(pdfCopyProvider.GetImportedPage(reader, pageNumber));
//关闭
sourceDocument.Close();
//关闭
reader.Close();
//返回
return fileOutput.FilePath;
}
/// <summary>
/// 将多个PDF文件合并为一个PDF文件 LastUpdateDate:2021-06-29 16:23:23.438 Author:Lingbug
/// </summary>
/// <param name="outputPdfFileName">新PDF文件名(自动识别是否带有.pdf后缀),为空默认为OutputMergePdfFileName</param>
/// <param name="sourcePdfPathList">要合并的源PDF文件相对路径集合</param>
/// <returns>新的PDF文件相对路径</returns>
public static string MergePdfs(string outputPdfFileName, params string[] sourcePdfPathList)
{
//校验
if (sourcePdfPathList.IsNullOrEmptyList()) throw new ErpFriendlyException("要合并的PDF相对路径集合不能为空!");
//过滤
sourcePdfPathList = sourcePdfPathList.Where(r => !r.IsNullOrWhiteSpaceString()).Distinct().ToArray();
//校验
if (sourcePdfPathList.IsNullOrEmptyList()) throw new ErpFriendlyException("要合并的PDF相对路径集合不能为空!");
//获取完整路径
var sourcePdfFullPathList = sourcePdfPathList.Select(sourcePdfPath =>
{
//完整路径
string sourcePdfFullPath = FileUtil.GetFullPath(sourcePdfPath);
//校验
if (!File.Exists(sourcePdfFullPath)) throw new ErpFriendlyException("要合并的PDF源文件不存在:" + sourcePdfPath);
//返回
return sourcePdfFullPath;
}).ToArray();
//结果文件
var fileOutput = GetOutputPdfFileInfo(outputPdfFileName, "OutputMergePdfFileName");
//读取器
PdfReader reader;
//文档
Document doc = new Document();
//写入器
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(fileOutput.FileFullPath, FileMode.Create));
//打开文档
doc.Open();
//内容容器
PdfContentByte cb = writer.DirectContent;
//页
PdfImportedPage newPage;
for (int i = 0; i < sourcePdfFullPathList.Length; i++)
{
//读取文件
reader = new PdfReader(sourcePdfFullPathList[i]);
//总页数
int totalPages = reader.NumberOfPages;
for (int j = 1; j <= totalPages; j++)
{
//读取页
newPage = writer.GetImportedPage(reader, j);
//页大小
doc.SetPageSize(reader.GetPageSize(j));
//开启新页
doc.NewPage();
//填充内容
cb.AddTemplate(newPage, 0, 0);
}
}
//关闭文档
doc.Close();
//返回
return fileOutput.FilePath;
}
/// <summary>
/// 构建输出PDF文件信息 LastUpdateDate:2021-06-29 16:14:28.454 Author:Lingbug
/// </summary>
/// <param name="outputPdfFileName"></param>
/// <param name="defaultOutputPdfFileName"></param>
/// <returns></returns>
private static SaveFileOutput GetOutputPdfFileInfo(string outputPdfFileName, string defaultOutputPdfFileName)
{
//默认名称
if (outputPdfFileName.IsNullOrWhiteSpaceString()) outputPdfFileName = defaultOutputPdfFileName;
//格式化
outputPdfFileName = outputPdfFileName.AutoAppendEnd(".pdf");
//结果文件
return new SaveFileOutput(outputPdfFileName, "UploadFiles", "Temp", "Pdfs");
}
}
}