首页 > 解决方案 > 使用 iTextSharp 克服 200 英寸 adobe 错误

问题描述

我正在将多页(分页)pdf 文档转换为单页(非分页)pdf 文档。我希望克服 adobe reader 的 200 英寸限制。

使用 iTextSharp.PdfReader 读取每个页面以创建目标文档的总高度并找到最大宽度。

创建文档的代码可以直接从分页 pdf 读取到非分页 pdf 中。使用 Chrome 或 Foxit 文件可以正常打开。当页面超过 200 英寸时,Adobe 会截断 200 英寸。在我的测试文件中,页面高度为 8.25 x 814 英寸。

将 UserUnits 更改为 4.07 (814/200) 会使 Adob​​e 将页面高度显示为 814 英寸,但仍会截断页面并将宽度显示为 33。

如果目标文件的宽​​度设置为 width/userunits (8.25/4.07),则目标文件中只显示剩下的 2 英寸。

复制部分代码:

RandomAccessFileOrArray ra = new RandomAccessFileOrArray(fn);

SizeF pageSize = new SizeF(pageWidth, pageHeight);
float USERUnitNewValue = ComputeUserUnit(pageSize);

if (pageHeight > 14400f)  
{
    USERUnitNewValue = pageHeight / 14400f;
}

float NewPageWidth = (pageWidth <= 14400f) ? pageWidth :  pageWidth* USERUnitNewValue;
float NewPageHeight = pageHeight * USERUnitNewValue;

FileInfo file1 = new FileInfo(newfn);
DirectoryInfo directory1 = file1.Directory;
if (!directory1.Exists)
    directory1.Create();


iTextSharp.text.Rectangle newPagesize = new iTextSharp.text.Rectangle(pageWidth, pageHeight);

Document newPdf = new Document(newPagesize);

PdfWriter writer = PdfWriter.GetInstance(newPdf, new FileStream(newfn, FileMode.Create));
writer.PdfVersion = PdfWriter.VERSION_1_6;

if (pageHeight > 14400)
{
    writer.Userunit = USERUnitNewValue;
}
newPdf.SetMargins(0f, 0f, 0f, 0f);
newPdf.Open();

PdfContentByte cb = writer.DirectContent;

float verticalPosition = pageHeight;
for (int pagenumber = 1; pagenumber <= n1; pagenumber++)
{
    if (pdfReader.NumberOfPages >= pagenumber)
    {
        verticalPosition = verticalPosition - pdfReader.GetPageSize(pagenumber).Height;
        cb.AddTemplate(writer.GetImportedPage(pdfReader, pagenumber), 0, verticalPosition);
    }
    else
    {
        break;
    }
}

newPdf.Close();
            

如果有人将原始文件发送到打印机,如何将原始文件复制到两个文件将保持相同大小的目标?

是的,这段代码中有一些冗余,因为我已经对此进行了一段时间的故障排除。

这里的关键问题是保持 8.25 x 814in 并仍然允许 adobe 打开文件的设置。

谢谢,

麦克风

标签: c#.netpdfitext

解决方案


谢谢大卫。在查看了 Lowagie 先生的文档和关于 addTemplate 的简要说明之后。cb.addTemplate(page, scale, 0, 0, scale, 0, 0) 代码已更新以利用新的用户单元和缩放。

现在可以在 Adob​​e 中打开并按预期报告页面长度

代码还是有点难看

            RandomAccessFileOrArray ra = new RandomAccessFileOrArray(fn);

            SizeF pageSize = GetPageSize(fn);
            PdfReader pdfReader = new PdfReader(fn);

            float USERUnitNewValue = ComputeUserUnit(pageSize);
            int n1 = pdfReader.NumberOfPages;

            if (pageSize.Height > 14400f)  //14400 value is 72 pixels per inch over 200 inches.  200 inches seems to be adobe limit to a page
            {  //determine the userunit to be used
                USERUnitNewValue = pageSize.Height / 14400f;
            }

            float NewPageWidth = (pageSize.Width <= 14400f) ? pageSize.Width / USERUnitNewValue : pageSize.Width / USERUnitNewValue;
            float NewPageHeight = pageSize.Height / USERUnitNewValue;

            FileInfo file1 = new FileInfo(newfn);
            DirectoryInfo directory1 = file1.Directory;
            if (!directory1.Exists)
                directory1.Create();

            iTextSharp.text.Rectangle newPagesize = new iTextSharp.text.Rectangle(NewPageWidth, NewPageHeight);

            Document newPdf = new Document(newPagesize);

            PdfWriter writer = PdfWriter.GetInstance(newPdf, new FileStream(newfn, FileMode.Create));
            writer.PdfVersion = PdfWriter.VERSION_1_6;

            if (pageSize.Height > 14400)
            {
                writer.Userunit = USERUnitNewValue;
            }
            newPdf.SetMargins(0f, 0f, 0f, 0f);
            newPdf.Open();

            PdfContentByte cb = writer.DirectContent;

            float verticalPosition = NewPageHeight;
            for (int pagenumber = 1; pagenumber <= n1; pagenumber++)
            {
                if (pdfReader.NumberOfPages >= pagenumber)
                {
                    /*convoluted page position.  First position should be 0,0
                     unlike other counters this starts as page 1 so we need to subtract the
                     first page height away so that we start at the bottom of the previous image
                     * hmm  seems that ths AddTemplate feature adds the pages in reverse order or 
                     * at least the coordinate system sets 0,0 at the bottom left of the page
                     */
                    float widthfactor = 1 / USERUnitNewValue;  //Page scaling (width)
                    float heightfactor = 1 / USERUnitNewValue; //Page scaling (height)
                    //vertical position needs to take into account the new page height taking new UserUnit in affect
                    verticalPosition = verticalPosition - (pdfReader.GetPageSize(pagenumber).Height / USERUnitNewValue);

                    cb.AddTemplate(writer.GetImportedPage(pdfReader, pagenumber), heightfactor, 0, 0, widthfactor, 0, verticalPosition);
                }
                else
                {
                    break;
                }
            }

            newPdf.Close();

再次感谢您的帮助,迈克


推荐阅读