为什么GetPageLabels的结果与Adobe Acrobat不同

时间:2015-09-04 08:48:14

标签: pdf itextsharp page-numbering

我在Adobe Acrobat X Pro中编辑pdf的页码。 Test PDF

  
      
  • 结果:      
        
    • 1-FrontCover
    •   
    • 2- FrontFold
    •   
    • 3-i
    •   
    • 4-ii
    •   
    • 5-iii
    •   
    • 6-1
    •   
    • 7-2
    •   
    • 8-3
    •   
    • 9-4
    •   
    • 10-5
    •   
    • 11-BackFold
    •   
    • 12后盖
    •   
  •   

但是这个GetPageLabels的结果是错误的

  
      
  • 页码:      
        
    • 0-FrontCover1
    •   
    • 1-FrontFold1
    •   
    • 2- FrontFoldi
    •   
    • 3- FrontFoldii
    •   
    • 4- FrontFoldiii
    •   
    • 5- FrontFold1
    •   
    • -6- FrontFold2
    •   
    • 7- FrontFold3
    •   
    • 8 FrontFold4
    •   
    • 9-FrontFold5
    •   
    • 10 BackFold1
    •   
    • 11-BackCover1
    •   
  •   

C#代码:

objLabels = PdfPageLabels.GetPageLabels(objReader);
TextBox1.Text += "page number:" + Environment.NewLine;
if (objLabels != null) {
    for (i = 0; i <= objLabels.Length - 1; i++) {
        TextBox1.Text += i + "-" + objLabels(i) + Environment.NewLine;
    }
}

如何获得像Adobe Acrobat X Pro这样的正确结果?

2 个答案:

答案 0 :(得分:1)

PdfPageLabels.GetPageLabels(PdfReader)中有一个小错误。遇到没有 P (前缀)条目的新页面标签字典时,它重置当前prefix值:

int pagecount = 1;
String prefix = "";
char type = 'D';
for (int i = 0; i < n; i++) {
    if (numberTree.ContainsKey(i)) {
        PdfDictionary d = (PdfDictionary)PdfReader.GetPdfObjectRelease(numberTree[i]);
        if (d.Contains(PdfName.ST)) {
            pagecount = ((PdfNumber)d.Get(PdfName.ST)).IntValue;
        }
        else {
            pagecount = 1;
        }
        if (d.Contains(PdfName.P)) {
            prefix = ((PdfString)d.Get(PdfName.P)).ToUnicodeString();
        }
        if (d.Contains(PdfName.S)) {
            type = ((PdfName)d.Get(PdfName.S)).ToString()[1];
        }
        else {
            type = 'e';
        }
    } 
    ...
}

您可以通过向相关else添加以下if子句来解决此问题:

        if (d.Contains(PdfName.P)) {
            prefix = ((PdfString)d.Get(PdfName.P)).ToUnicodeString();
        }
        else
        {
            prefix = "";
        }

随着这种变化,我得到了

page number:
 0 - FrontCover
 1 - FrontFold
 2 - i
 3 - ii
 4 - iii
 5 - 1
 6 - 2
 7 - 3
 8 - 4
 9 - 5
10 - BackFold
11 - BackCover

PS:Java iText版本中存在同样的问题,在ReadPageLabels.java中进行了测试。

答案 1 :(得分:0)

感谢您帮助解决我的问题, 这是我的完整计划。

public string[] ReadPageLabel(PdfReader objReader, int intPageCount)
{
    PdfDictionary objDictionary ;
    Dictionary<int, PdfObject> objTree ;
    string[] arrLabels ;
    int i ;
    char chrLabelKind ;
    string strLabelPrefix ;
    int intLableNumber ;
    //PdfPageLabels is wrong
    //arrLabels = PdfPageLabels.GetPageLabels(objReader)


    arrLabels = new string[intPageCount];

    if (objReader.Catalog.Get(PdfName.PAGELABELS) != null) {
        objTree = PdfNumberTree.ReadTree(PdfReader.GetPdfObjectRelease(objReader.Catalog.Get(PdfName.PAGELABELS)));

        chrLabelKind = 'D';
        strLabelPrefix = "";
        intLableNumber = 1;
        for (i = 0; i <= intPageCount - 1; i++) {
            if (objTree.ContainsKey(i)) { //if reset page number
                objDictionary = PdfReader.GetPdfObjectRelease(objTree[i]);
                //PdfName.S:Number Kind
                if (objDictionary.Contains(PdfName.S)) {
                    chrLabelKind = ((PdfName)objDictionary.Get(PdfName.S)).ToString()(1);
                    //PdfName.S:/R,/r,/A,/a,/e,/D,ToString()(1)get alphabet of Index=1
                } else {
                    chrLabelKind = 'e';
                }
                //PdfName.P:Prefix
                if (objDictionary.Contains(PdfName.P)) {
                    strLabelPrefix = ((PdfString)objDictionary.Get(PdfName.P)).ToUnicodeString();               
                } else {
                    strLabelPrefix = "";
                }
                //PdfName.ST:Start Number
                if (objDictionary.Contains(PdfName.ST)) {
                    intLableNumber = ((PdfNumber)objDictionary.Get(PdfName.ST)).IntValue;
                } else {
                    intLableNumber = 1;
                }
            }
            switch (chrLabelKind) {
                case 'R':
                    //I,II,III
                    arrLabels[i] = strLabelPrefix + factories.RomanNumberFactory.GetUpperCaseString(intLableNumber);
                    break;
                case 'r':
                    //i,ii,iii
                    arrLabels[i] = strLabelPrefix + factories.RomanNumberFactory.GetLowerCaseString(intLableNumber);
                    break;
                case 'A':
                    //A,B,C
                    arrLabels[i] = strLabelPrefix + factories.RomanAlphabetFactory.GetUpperCaseString(intLableNumber);
                    break;
                case 'a':
                    //a,b,c
                    arrLabels[i] = strLabelPrefix + factories.RomanAlphabetFactory.GetLowerCaseString(intLableNumber);
                    break;
                case 'e':
                    //no number kind
                    arrLabels[i] = strLabelPrefix;
                    break;
                default:
                    //1,2,3
                    arrLabels[i] = strLabelPrefix + intLableNumber;
                    break;
            }
            intLableNumber += 1;

        }
    } else {
        for (i = 0; i <= intPageCount - 1; i++) {
            arrLabels[i] = i + 1;
        }
    }
    return arrLabels;
}