#c# #pdf #merge #itextsharp
#c# #PDF #объединение #itext
Вопрос:
Ну, я пытаюсь объединить несколько PDF-файлов в один.
I не выдает ошибок при компиляции. Сначала я попытался объединить документы, но это пошло не так, потому что я работаю с таблицами.
Это asp.net скрытый код
if (Button.Equals("PreviewWord")) {
String eventTemplate = Server.MapPath("/ERAS/Badges/Template/EventTemp" EventName ".doc");
String SinglePreview = Server.MapPath("/ERAS/Badges/Template/PreviewSingle" EventName ".doc");
String PDFPreview = Server.MapPath("/ERAS/Badges/Template/PDFPreviewSingle" EventName ".pdf");
String previewPDFs = Server.MapPath("/ERAS/Badges/Template/PreviewPDFs" EventName ".pdf");
if (System.IO.File.Exists((String)eventTemplate))
{
if (vulGegevensIn == true)
{
//This creates a Worddocument and fills in names etc from database
CreateWordDocument(vulGegevensIn, eventTemplate, SinglePreview, false);
//This saves the SinglePreview.doc as a PDF @param place of PDFPreview
CreatePDF(SinglePreview, PDFPreview);
//Trying to merge
String[] previewsSmall=new String[1];
previewsSmall[0] = PDFPreview;
PDFMergenITextSharp.MergeFiles(previewPDFs, previewsSmall);
}
// merge PDFs here...........................;
//here
//no here//
//...
} }
Это класс pdfmergenitextsharp
общедоступный статический класс PDFMergenITextSharp {
public static void MergeFiles(string destinationFile, string[] sourceFiles)
{
try
{
int f = 0;
// we create a reader for a certain document
PdfReader reader = new PdfReader(sourceFiles[f]);
// we retrieve the total number of pages
int n = reader.NumberOfPages;
//Console.WriteLine("There are " n " pages in the original file.");
// step 1: creation of a document-object
Document document = new Document(reader.GetPageSizeWithRotation(1));
// step 2: we create a writer that listens to the document
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(destinationFile, FileMode.Create));
// step 3: we open the document
document.Open();
PdfContentByte cb = writer.DirectContent;
PdfImportedPage page;
int rotation;
// step 4: we add content
while (f < sourceFiles.Length)
{
int i = 0;
while (i < n)
{
i ;
document.SetPageSize(reader.GetPageSizeWithRotation(i));
document.NewPage();
page = writer.GetImportedPage(reader, i);
rotation = reader.GetPageRotation(i);
if (rotation == 90 || rotation == 270)
{
cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height);
}
else
{
cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
}
//Console.WriteLine("Processed page " i);
}
f ;
if (f < sourceFiles.Length)
{
reader = new PdfReader(sourceFiles[f]);
// we retrieve the total number of pages
n = reader.NumberOfPages;
//Console.WriteLine("There are " n " pages in the original file.");
}
}
// step 5: we close the document
document.Close();
}
catch (Exception e)
{
string strOb = e.Message;
}
}
public static int CountPageNo(string strFileName)
{
// we create a reader for a certain document
PdfReader reader = new PdfReader(strFileName);
// we retrieve the total number of pages
return reader.NumberOfPages;
}
}
Комментарии:
1. Используйте PdfCopy вместо PdfWriter. Должно быть несколько примеров и связанных с ними вопросов.
2. @Liquid — CreatePDF (SinglePreview, PDFPreview); Не могли бы вы, пожалуйста, поделиться тем, как вы создали pdf из doc. Будет очень полезно, если вы предоставите некоторые подробности о том, как вы конвертировали. Я надеюсь, что вы используете iTextSharp для преобразования документа в pdf.
Ответ №1:
Я нашел ответ:
Вместо второго метода добавьте больше файлов в первый массив входных файлов.
public static void CombineMultiplePDFs(string[] fileNames, string outFile)
{
// step 1: creation of a document-object
Document document = new Document();
//create newFileStream object which will be disposed at the end
using (FileStream newFileStream = new FileStream(outFile, FileMode.Create))
{
// step 2: we create a writer that listens to the document
PdfCopy writer = new PdfCopy(document, newFileStream);
// step 3: we open the document
document.Open();
foreach (string fileName in fileNames)
{
// we create a reader for a certain document
PdfReader reader = new PdfReader(fileName);
reader.ConsolidateNamedDestinations();
// step 4: we add content
for (int i = 1; i <= reader.NumberOfPages; i )
{
PdfImportedPage page = writer.GetImportedPage(reader, i);
writer.AddPage(page);
}
PRAcroForm form = reader.AcroForm;
if (form != null)
{
writer.CopyAcroForm(reader);
}
reader.Close();
}
// step 5: we close the document and writer
writer.Close();
document.Close();
}//disposes the newFileStream object
}
Комментарии:
1. @liquid — извините, можете ли вы указать, какие ссылки вы использовали, чтобы это сработало?
2. «PdfCopy не содержит определения для CopyAcroForm»
3. Пришлось изменить строку
PRAcroForm form = reader.AcroForm;
наPrAcroForm form = reader.AcroForm;
(маленькая «r» вместо заглавной, иначе я получил ошибку — однако правка не была принята во внимание в этой части …)4. @misanthrop правка не была принята во внимание, поскольку имя класса этого объекта написано с большой буквы R «PRAcroForm». Но я не знаю, какую версию iTextSharp вы используете. Но я все равно рад, что это помогло вам на вашем пути
5. Мы используем iTextSharp.LGPLv2.Core, который действительно является неофициальным портом iTextSharp (версия 4.1.6), возможно, это как-то связано с этим… возможно, этот комментарий поможет и кому-то другому =)
Ответ №2:
Я нашел очень хорошее решение на этом сайте: http://weblogs.sqlteam.com/mladenp/archive/2014/01/10/simple-merging-of-pdf-documents-with-itextsharp-5-4-5.aspx
Я обновляю метод в этом режиме :
public static bool MergePdfs(IEnumerable<string> fileNames, string targetFileName)
{
bool success = true;
using (FileStream stream = new(targetFileName, FileMode.Create))
{
Document document = new();
PdfCopy pdf = new(document, stream);
PdfReader? reader = null;
try
{
document.Open();
foreach (string file in fileNames)
{
reader = new PdfReader(file);
pdf.AddDocument(reader);
reader.Close();
}
}
catch (Exception)
{
success = false;
reader?.Close();
}
finally
{
document?.Close();
}
}
return success;
}
Комментарии:
1. Я предпочитаю это решение, поскольку оно не включает устаревшую
CopyAcroForm
функциональность, которая больше не доступна в последней версииitextsharp
.2. У меня отлично работает с несколькими документами и последней версией itextsharp, доступной на nuget 🙂
3. Насколько я могу судить, практически нет причин не использовать PdfSmartCopy поверх PdfCopy. По крайней мере, для меня экономия размера PDF-файла была очень значительной.
Ответ №3:
Код для объединения PDF-файлов в Itextsharp
public static void Merge(List<String> InFiles, String OutFile)
{
using (FileStream stream = new FileStream(OutFile, FileMode.Create))
using (Document doc = new Document())
using (PdfCopy pdf = new PdfCopy(doc, stream))
{
doc.Open();
PdfReader reader = null;
PdfImportedPage page = null;
//fixed typo
InFiles.ForEach(file =>
{
reader = new PdfReader(file);
for (int i = 0; i < reader.NumberOfPages; i )
{
page = pdf.GetImportedPage(reader, i 1);
pdf.AddPage(page);
}
pdf.FreeReader(reader);
reader.Close();
File.Delete(file);
});
}
}
Комментарии:
1. У человека, копирующего и вставляющего ваш код, не прочитав его серьезно, могут возникнуть серьезные проблемы: не в каждом случае использования слияния исходные файлы должны быть удалены!
2. Это все еще работало. Убедитесь, что вы понимаете, какой файл. Удалить (файл); выполнить.
Ответ №4:
Использование iTextSharp.dll
protected void Page_Load(object sender, EventArgs e)
{
String[] files = @"C:ENROLLDOCSA1.pdf,C:ENROLLDOCSA2.pdf".Split(',');
MergeFiles(@"C:ENROLLDOCSNew1.pdf", files);
}
public void MergeFiles(string destinationFile, string[] sourceFiles)
{
if (System.IO.File.Exists(destinationFile))
System.IO.File.Delete(destinationFile);
string[] sSrcFile;
sSrcFile = new string[2];
string[] arr = new string[2];
for (int i = 0; i <= sourceFiles.Length - 1; i )
{
if (sourceFiles[i] != null)
{
if (sourceFiles[i].Trim() != "")
arr[i] = sourceFiles[i].ToString();
}
}
if (arr != null)
{
sSrcFile = new string[2];
for (int ic = 0; ic <= arr.Length - 1; ic )
{
sSrcFile[ic] = arr[ic].ToString();
}
}
try
{
int f = 0;
PdfReader reader = new PdfReader(sSrcFile[f]);
int n = reader.NumberOfPages;
Response.Write("There are " n " pages in the original file.");
Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(destinationFile, FileMode.Create));
document.Open();
PdfContentByte cb = writer.DirectContent;
PdfImportedPage page;
int rotation;
while (f < sSrcFile.Length)
{
int i = 0;
while (i < n)
{
i ;
document.SetPageSize(PageSize.A4);
document.NewPage();
page = writer.GetImportedPage(reader, i);
rotation = reader.GetPageRotation(i);
if (rotation == 90 || rotation == 270)
{
cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height);
}
else
{
cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
}
Response.Write("n Processed page " i);
}
f ;
if (f < sSrcFile.Length)
{
reader = new PdfReader(sSrcFile[f]);
n = reader.NumberOfPages;
Response.Write("There are " n " pages in the original file.");
}
}
Response.Write("Success");
document.Close();
}
catch (Exception e)
{
Response.Write(e.Message);
}
}
Комментарии:
1. возникает проблема при использовании этого, когда мой контент отключается?
Ответ №5:
Объединение массивов байтов нескольких файлов PDF:
public static byte[] MergePDFs(List<byte[]> pdfFiles)
{
if (pdfFiles.Count > 1)
{
PdfReader finalPdf;
Document pdfContainer;
PdfWriter pdfCopy;
MemoryStream msFinalPdf = new MemoryStream();
finalPdf = new PdfReader(pdfFiles[0]);
pdfContainer = new Document();
pdfCopy = new PdfSmartCopy(pdfContainer, msFinalPdf);
pdfContainer.Open();
for (int k = 0; k < pdfFiles.Count; k )
{
finalPdf = new PdfReader(pdfFiles[k]);
for (int i = 1; i < finalPdf.NumberOfPages 1; i )
{
((PdfSmartCopy)pdfCopy).AddPage(pdfCopy.GetImportedPage(finalPdf, i));
}
pdfCopy.FreeReader(finalPdf);
}
finalPdf.Close();
pdfCopy.Close();
pdfContainer.Close();
return msFinalPdf.ToArray();
}
else if (pdfFiles.Count == 1)
{
return pdfFiles[0];
}
return null;
}
Ответ №6:
Я нигде не вижу этого решения и предположительно… по словам одного человека, правильный способ сделать это — с помощью copyPagesTo(). Это действительно работает, я протестировал это. Ваш пробег может варьироваться в зависимости от города и открытой дороги. Удачи.
public static bool MergePDFs(List<string> lststrInputFiles, string OutputFile, out int iPageCount, out string strError)
{
strError = string.Empty;
PdfWriter pdfWriter = new PdfWriter(OutputFile);
PdfDocument pdfDocumentOut = new PdfDocument(pdfWriter);
PdfReader pdfReader0 = new PdfReader(lststrInputFiles[0]);
PdfDocument pdfDocument0 = new PdfDocument(pdfReader0);
int iFirstPdfPageCount0 = pdfDocument0.GetNumberOfPages();
pdfDocument0.CopyPagesTo(1, iFirstPdfPageCount0, pdfDocumentOut);
iPageCount = pdfDocumentOut.GetNumberOfPages();
for (int ii = 1; ii < lststrInputFiles.Count; ii )
{
PdfReader pdfReader1 = new PdfReader(lststrInputFiles[ii]);
PdfDocument pdfDocument1 = new PdfDocument(pdfReader1);
int iFirstPdfPageCount1 = pdfDocument1.GetNumberOfPages();
iPageCount = iFirstPdfPageCount1;
pdfDocument1.CopyPagesTo(1, iFirstPdfPageCount1, pdfDocumentOut);
int iFirstPdfPageCount00 = pdfDocumentOut.GetNumberOfPages();
}
pdfDocumentOut.Close();
return true;
}
Комментарии:
1. Ваше решение подходит для iText 7, в то время как вопрос и другие ответы сосредоточены на iText 5.
2. Это правильно и почему я это опубликовал. Практически все другие ответы, которые я нашел, были устаревшими, но я должен был указать на разницу. Каждый ответ, который я нашел, был для iText 5, поэтому я решил, что опубликовать один для текущего iText 7 было хорошей идеей.
Ответ №7:
Пожалуйста, также посетите и прочтите эту статью, где я подробно объяснил все о том, как объединить несколько PDF-файлов в один PDF с помощью Itextsharp на C #
Реализация:
try
{
string FPath = "";
// Create For loop for get/create muliple report on single click based on row of gridview control
for (int j = 0; j < Gridview1.Rows.Count; j )
{
// Return datatable for data
DataTable dtDetail = new My_GlobalClass().GetDataTable(Convert.ToInt32(Gridview1.Rows[0]["JobId"]));
int i = Convert.ToInt32(Gridview1.Rows[0]["JobId"]);
if (dtDetail.Rows.Count > 0)
{
// Create Object of ReportDocument
ReportDocument cryRpt = new ReportDocument();
//Store path of .rpt file
string StrPath = Application.StartupPath "\RPT";
StrPath = StrPath "\";
StrPath = StrPath "rptCodingvila_Articles_Report.rpt";
cryRpt.Load(StrPath);
// Assign Report Datasource
cryRpt.SetDataSource(dtDetail);
// Assign Reportsource to Report viewer
CryViewer.ReportSource = cryRpt;
CryViewer.Refresh();
// Store path/name of pdf file one by one
string StrPathN = Application.StartupPath "\Temp" "\Codingvila_Articles_Report" i.ToString() ".Pdf";
FPath = FPath == "" ? StrPathN : FPath "," StrPathN;
// Export Report in PDF
cryRpt.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, StrPathN);
}
}
if (FPath != "")
{
// Check for File Existing or Not
if (System.IO.File.Exists(Application.StartupPath "\Temp" "\Codingvila_Articles_Report.pdf"))
System.IO.File.Delete(Application.StartupPath "\Temp" "\Codingvila_Articles_Report.pdf");
// Split and store pdf input file
string[] files = FPath.Split(',');
// Marge Multiple PDF File
MargeMultiplePDF(files, Application.StartupPath "\Temp" "\Codingvila_Articles_Report.pdf");
// Open Created/Marged PDF Output File
Process.Start(Application.StartupPath "\Temp" "\Codingvila_Articles_Report.pdf");
// Check and Delete Input file
foreach (string item in files)
{
if (System.IO.File.Exists(item.ToString()))
System.IO.File.Delete(item.ToString());
}
}
}
catch (Exception ex)
{
XtraMessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
Создать функцию для Marge PDF
public static void MargeMultiplePDF(string[] PDFfileNames, string OutputFile)
{
iTextSharp.text.Document PDFdoc = new iTextSharp.text.Document();
using (System.IO.FileStream MyFileStream = new System.IO.FileStream(OutputFile, System.IO.FileMode.Create))
{
iTextSharp.text.pdf.PdfCopy PDFwriter = new iTextSharp.text.pdf.PdfCopy(PDFdoc, MyFileStream);
if (PDFwriter == null)
{
return;
}
PDFdoc.Open();
foreach (string fileName in PDFfileNames)
{
iTextSharp.text.pdf.PdfReader PDFreader = new iTextSharp.text.pdf.PdfReader(fileName);
PDFreader.ConsolidateNamedDestinations();
for (int i = 1; i <= PDFreader.NumberOfPages; i )
{
iTextSharp.text.pdf.PdfImportedPage page = PDFwriter.GetImportedPage(PDFreader, i);
PDFwriter.AddPage(page);
}
iTextSharp.text.pdf.PRAcroForm form = PDFreader.AcroForm;
if (form != null)
{
PDFwriter.CopyAcroForm(PDFreader);
}
PDFreader.Close();
}
PDFwriter.Close();
PDFdoc.Close();
}
}
Комментарии:
1. Для объединения с iText (Sharp) 2.x, 4.x и 5.x обычно лучше использовать решения на
PdfCopy
основе, чем наPdfWriter
основе, подобные вашему.