为什么 GetPageLabels 的结果与 Adobe Acrobat 不同
Why result of GetPageLabels is different from the Adobe Acrobat
我在 Adobe Acrobat X Pro 中编辑 pdf 的页码。
Test PDF
- result:
- 1-FrontCover
- 2-FrontFold
- 3-i
- 4-ii
- 5-iii
- 6-1
- 7-2
- 8-3
- 9-4
- 10-5
- 11-BackFold
- 12-BackCover
但是GetPageLabels的这个结果是错误的
- page number:
- 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一样正确的结果?
PdfPageLabels.GetPageLabels(PdfReader)
中有一个小错误。当遇到没有 P(前缀)条目的新页面标签字典时,它会 not 重置当前 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:在 ReadPageLabels.java.
中测试的 Java iText 版本中存在同样的问题
谢谢你帮我解决了问题,
这是我的完整程序。
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;
}
我在 Adobe Acrobat X Pro 中编辑 pdf 的页码。 Test PDF
- result:
- 1-FrontCover
- 2-FrontFold
- 3-i
- 4-ii
- 5-iii
- 6-1
- 7-2
- 8-3
- 9-4
- 10-5
- 11-BackFold
- 12-BackCover
但是GetPageLabels的这个结果是错误的
- page number:
- 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一样正确的结果?
PdfPageLabels.GetPageLabels(PdfReader)
中有一个小错误。当遇到没有 P(前缀)条目的新页面标签字典时,它会 not 重置当前 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:在 ReadPageLabels.java.
中测试的 Java iText 版本中存在同样的问题谢谢你帮我解决了问题, 这是我的完整程序。
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;
}