使用 iTextSharp 在 C# 中旋转 PDF

Posted

技术标签:

【中文标题】使用 iTextSharp 在 C# 中旋转 PDF【英文标题】:Rotating PDF in C# using iTextSharp 【发布时间】:2011-04-04 11:46:44 【问题描述】:

我正在使用以下函数将 pdf 一分为二。

虽然它正在拆分 pdf,但内容却是颠倒的。我如何将它旋转 180 度。

请帮忙。下面是相同的代码

private static void ExtractPages(string inputFile, string outputFile,
  int start, int end)
     
         // get input document
         PdfReader inputPdf = new PdfReader(inputFile);

         // retrieve the total number of pages
         int pageCount = inputPdf.NumberOfPages;

         if (end < start || end > pageCount)
         
             end = pageCount;
         

         // load the input document
         Document inputDoc =
             new Document(inputPdf.GetPageSizeWithRotation(1));

         // create the filestream
         using (FileStream fs = new FileStream(outputFile, FileMode.Create))
         
             // create the output writer
             PdfWriter outputWriter = PdfWriter.GetInstance(inputDoc, fs);
             inputDoc.Open();

             PdfContentByte cb1 = outputWriter.DirectContent;

             // copy pages from input to output document
             for (int i = start; i <= end; i++)
             
                 inputDoc.SetPageSize(inputPdf.GetPageSizeWithRotation(1));
                 inputDoc.NewPage();

                 PdfImportedPage page =
                     outputWriter.GetImportedPage(inputPdf, i);
                 int rotation = inputPdf.GetPageRotation(i);


                 if (rotation == 90 || rotation == 270)
                 
                     cb1.AddTemplate(page, 0, -1f, 1f, 0, 0,
                         inputPdf.GetPageSizeWithRotation(i).Height);

                 
                 else
                 
                     cb1.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
                 

             

             inputDoc.Close();
         
     

【问题讨论】:

【参考方案1】:

我发现上述答案在所有 4 个主要旋转中都没有正确旋转。

以下是我正确处理 0、90、180 和 270 的代码。这已经通过在每个方向旋转的 PDF 进行了测试。

var pageRotation = reader.GetPageRotation(currentPageIndex);
var pageWidth = reader.GetPageSizeWithRotation(currentPageIndex).Width;
var pageHeight = reader.GetPageSizeWithRotation(currentPageIndex).Height;
switch (pageRotation)

    case 0:
        writer.DirectContent.AddTemplate(importedPage, 1f, 0, 0, 1f, 0, 0);
        break;

    case 90:
        writer.DirectContent.AddTemplate(importedPage, 0, -1f, 1f, 0, 0, pageHeight);
        break;

    case 180:
        writer.DirectContent.AddTemplate(importedPage, -1f, 0, 0, -1f, pageWidth, pageHeight);
        break;

    case 270:
        writer.DirectContent.AddTemplate(importedPage, 0, 1f, -1f, 0, pageWidth, 0);
        break;

    default:
        throw new InvalidOperationException(string.Format("Unexpected page rotation: [0].", pageRotation));

【讨论】:

+1: 显然 case 0: 可以缩短为 writer.DirectContent.AddTemplate(importedPage, 0, 0); 您的回答刚刚帮助我解决了将现有 PDF 再旋转 90、180 或 270 度的问题 :)如果这些参数记录在某处,那就太好了,因为我收集它们是矩阵变换(?)。非常感谢。 已旋转页面的旋转还有一个问题。我使用了您的答案,并添加了一个带有附加页面大小/旋转操作的答案,以允许旋转已旋转的页面。【参考方案2】:

你应该试试这个。它对我有用:

                if (rotation == 90 || rotation == 270)
                

                    if (rotation == 90)
                    
                        cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(pagenumber).Height);
                    
                    if (rotation == 270)
                    
                        cb.AddTemplate(page, 0, 1.0F, -1.0F, 0, reader.GetPageSizeWithRotation(pagenumber).Width, 0);

                    

                
                else
                
                    cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
                

【讨论】:

【参考方案3】:

@TimS' 的答案非常接近完美,并为AddTemplate 提供了正确的参数,但我需要添加一些内容以允许页面 的 PDF 旋转 90、180、270已经有 0、90、180 或 270 的旋转

假设RotateFlipType rotateFlipType 的参数被传递给函数以指定旋转(来自 GDI+ RotateFlip 调用的方便枚举):

iTextSharp.text.pdf.PdfContentByte cb = writer.DirectContent;
iTextSharp.text.pdf.PdfImportedPage page;
int rotation;
int i = 0;
while (i < pageCount)

    i++;
    var pageSize = reader.GetPageSizeWithRotation(i);

    // Pull in the page from the reader
    page = writer.GetImportedPage(reader, i);

    // Get current page rotation in degrees
    rotation = pageSize.Rotation;

    // Default to the current page size
    iTextSharp.text.Rectangle newPageSize = null;

    // Apply our additional requested rotation (switch height and width as required)
    switch (rotateFlipType)
    
        case RotateFlipType.RotateNoneFlipNone:
            newPageSize = new iTextSharp.text.Rectangle(pageSize);
            break;
        case RotateFlipType.Rotate90FlipNone:
            rotation += 90;
            newPageSize = new iTextSharp.text.Rectangle(pageSize.Height, pageSize.Width, rotation);
            break;
        case RotateFlipType.Rotate180FlipNone:
            rotation += 180;
            newPageSize = new iTextSharp.text.Rectangle(pageSize.Width, pageSize.Height, rotation);
            break;
        case RotateFlipType.Rotate270FlipNone:
            rotation += 270;
            newPageSize = new iTextSharp.text.Rectangle(pageSize.Height, pageSize.Width, rotation);
            break;
    

    // Cap rotation into the 0-359 range for subsequent check
    rotation %= 360;

    document.SetPageSize(newPageSize);
    document.NewPage();

    // based on the rotation write out the page dimensions
    switch (rotation)
    
        case 0:
            cb.AddTemplate(page, 0, 0);
            break;
        case 90:
            cb.AddTemplate(page, 0, -1f, 1f, 0, 0, newPageSize.Height);
            break;
        case 180:
            cb.AddTemplate(page, -1f, 0, 0, -1f, newPageSize.Width, newPageSize.Height);
            break;
        case 270:
            cb.AddTemplate(page, 0, 1f, -1f, 0, newPageSize.Width, 0);
            break;
        default:
            throw new System.Exception(string.Format("Unexpected rotation of 0 degrees", rotation));
            break;
    

希望这将有助于其他希望纠正传入 PDF 旋转的人。我花了 2 天时间来完善它。

【讨论】:

你的代码就像一个魅力。非常感谢。你拯救了我的一天。 @RolandDeschain:很高兴它有帮助:)【参考方案4】:

我试过你的代码,它对我来说很好;分页保持原来的方向。

解决方法可能是将页面显式旋转 180 度。

替换:

cb1.AddTemplate(page, 1f, 0, 0, 1f, 0, 0); 

与:

cb1.AddTemplate(page, -1f, 0, 0, -1f, 
                inputPdf.GetPageSizeWithRotation(i).Width, 
                inputPdf.GetPageSizeWithRotation(i).Height);

如果您对 inputPdf.GetPageRotation(i) 的调用返回 180,那么您可以在随后的 if 语句中处理此问题(使用我建议的轮换代码 == 180)。

【讨论】:

【参考方案5】:

以上代码稍作改动 旧代码

case 270:
    writer.DirectContent.AddTemplate(importedPage, 0, 1f, -1f, 0, pageWidth, 0);

新代码

case 270:
    writer.DirectContent.AddTemplate(importedPage, 0, 1f, -1f, 0, pageHeight, 0);

这将解决 270 度旋转的问题

【讨论】:

上面的代码在 iTextSharp v 5.5 上完全没问题。

以上是关于使用 iTextSharp 在 C# 中旋转 PDF的主要内容,如果未能解决你的问题,请参考以下文章

iTextSharp 从现有的 PDF 模板生成 PDF

itextsharp 合并调整大小并取消旋转 pdf

C#工具类:使用iTextSharp操作PDF文档

C#生成PDF总结

iTextSharp PDF 使用 C# 读取突出显示的文本(突出显示注释)

c#中带有html的itextsharp [重复]