Эта страница может содержать автоматически переведенный текст.

Разделение PDF-документов в C# и VB.NET

Библиотека Docotic.Pdf позволяет разделить PDF-документ на набор меньших файлов. Можно извлекать отдельные страницы или диапазоны страниц. Также можно разделять PDF-документы по определенным критериям.

Разделение PDF-документов

Docotic.Pdf поставляется с платными лицензиями, но в некоторых случаях он бесплатен. Получите библиотеку и бесплатный временный лицензионный ключ на странице Скачать C# .NET библиотеку PDF.

Основы разделения PDF

Методы PdfDocument.CopyPages позволяют копировать страницы из объектов PdfDocument. Это основной API Docotic.Pdf для разделения PDF-документов.

Разделить PDF на отдельные страницы

Следующий код C# сохраняет каждую страницу PDF в отдельный файл:

using var pdf = new PdfDocument("source.pdf");

for (int i = 0; i < pdf.PageCount; ++i)
{
    using PdfDocument copy = pdf.CopyPages(i, 1);
    copy.RemoveUnusedResources();
    copy.Save(i + ".pdf");
}

Метод PdfDocument.RemoveUnusedResources помогает уменьшить размер выходных файлов. Он полезен, когда скопированные страницы ссылаются на неиспользуемые шрифты, изображения, шаблоны. Подробнее о сжатии PDF см. в разделе Оптимизировать выходные файлы.

Разделить на группы страниц

Метод CopyPages поддерживает копирование любого диапазона страниц. Этот фрагмент кода показывает, как извлечь третью и первую страницы:

using var pdf = new PdfDocument(@"source.pdf");

using PdfDocument copy = pdf.CopyPages([2, 0]);
copy.RemoveUnusedResources();
copy.Save("result.pdf");

Порядок индексов страниц важен. Он задает порядок страниц в результирующем документе.

Попробуйте пример кода Копировать страницы из GitHub.

Разделить PDF по условию

Можно разделять документы по содержимому. Это полезно, если заранее неизвестно, какие страницы нужно извлечь. Например, можно извлечь страницы, содержащие определенный текст:

string textToFind = ".NET Standard";
using var pdf = new PdfDocument("C# in depth.pdf");
var pageIndexes = new List<int>();
for (int i = 0; i < pdf.Pages.Count; i++)
{
    string pageText = pdf.Pages[i].GetText();
    if (pageText.Contains(textToFind, StringComparison.CurrentCultureIgnoreCase))
        pageIndexes.Add(i);
}

if (pageIndexes.Count > 0)
{
    using var copy = pdf.CopyPages(pageIndexes.ToArray());
    copy.RemoveUnusedResources();
    copy.Save(textToFind + ".pdf");
}

Подробнее о извлечении текста можно прочитать в статье Извлечение текста из PDF в C# и VB.NET.

Расширенное разделение PDF

Извлечь страницы

Методы CopyPages не изменяют связанный объект PdfDocument. Также есть методы PdfDocument.ExtractPages. Они позволяют удалить извлеченные страницы из документа:

using var pdf = new PdfDocument(@"source.pdf");

using PdfDocument copy = pdf.ExtractPages(0, 3);
copy.Save("extracted.pdf");

pdf.Save("original.pdf");

Можно попробовать соответствующий пример кода Извлечь страницы из GitHub.

Удалить и упорядочить страницы

Методы CopyPages и ExtractPages создают новый документ с выбранными страницами. Альтернативный вариант — удалить страницы из текущего документа:

using var pdf = new PdfDocument(@"source.pdf");
pdf.RemovePages(0, 3);
pdf.Save("remaining.pdf");

Также можно переупорядочить страницы после удаления. См. примеры кода в этих разделах:

Оптимизировать выходные файлы

Ранее я использовал метод RemoveUnusedResources для оптимизации результирующих файлов. Docotic.Pdf предоставляет больше возможностей для сжатия PDF. Например, можно удалить структурную информацию или сжать изображения. Дополнительные сведения см. в статье Сжатие PDF-документов в C# и VB.NET. Также можно попробовать пример кода Сжать PDF документ в .NET из GitHub.

Разделение PDF иногда используют, чтобы получить файлы страниц меньше определенного лимита. В таких случаях можно измерить получившийся размер и при необходимости сжать файл. Пример кода:

using var pdf = new PdfDocument("source.pdf");

using PdfDocument copy = pdf.CopyPages(0, 1);
copy.RemoveUnusedResources();

using var ms = new MemoryStream();
copy.Save(ms);

var limit = 1024 * 1024;
if (ms.Length > limit)
{
    compress(copy);
    copy.Save("result.pdf");
}

Обратите внимание, что может быть невозможно сжать PDF-файл ниже определенного лимита. Результат зависит от содержимого файла и значения лимита.

Извлечь содержимое страницы

При разделении также можно изменять содержимое страницы. Например, можно масштабировать извлеченные страницы перед использованием их в PDF-imposition. Попробуйте связанный проект-пример Создать XObject со страницы из GitHub.

Или можно удалить либо заменить часть содержимого на извлеченных страницах. См. пример кода Копирование текста, путей и изображений, который показывает, как копировать объекты PDF-страницы.

Разделить PDF в изображения

Docotic.Pdf также позволяет разделять PDF-документ на изображения страниц. Подробнее см. в статье Преобразование PDF в изображение в C# и VB.NET.

Разделение в параллельных потоках

Для больших документов может понадобиться распараллелить разделение PDF. Класс PdfDocument не потокобезопасен. Но можно использовать отдельные объекты PdfDocument в каждом потоке:

string fileName = "source.pdf";
using var temp = new PdfDocument(fileName);
int pageCount = temp.PageCount;

Parallel.For(0, pageCount, i =>
{
    using var pdf = new PdfDocument(fileName);
    using var copy = pdf.CopyPages(i, 1);
    copy.RemoveUnusedResources();
    copy.Save($"split_{i}.pdf");
});

Обратите внимание, что однопоточный код обычно работает быстрее. Многопоточное решение связано с накладными расходами на разбор дополнительных объектов PdfDocument. Используйте однопоточную версию, если только тесты не докажут, что параллельный код работает быстрее.