【问题标题】:Read roman page number of page读取罗马页码的页码
【发布时间】:2015-03-20 10:44:57
【问题描述】:

在 Adob​​e Reader 中,电子书的第一页可以有罗马格式的页码,如下图所示

图片:http://i.stack.imgur.com/GSm0Q.jpg

我想用 iText 读取这些页码(不是索引页码),但我不知道应该使用哪些属性(标签或注释..)。我已经可以用 PdfReader 打开文件,循环浏览所有页面,但不知道我应该访问这些罗马数字的什么

using (Stream pdfStream = new FileStream(sourceFileName, FileMode.Open))
{
    PdfReader pdfReader = new PdfReader(pdfStream);
    for (int index = 1; index <= pdfReader.NumberOfPages; index++)
    {

    }
}

谢谢。

【问题讨论】:

    标签: itextsharp itext


    【解决方案1】:

    您正在寻找PageLabelExample。在此示例中,我们有一个 PDF,page_labels.pdf,其页面编号如下:

    listPageLabels()方法中,我们创建一个包含所有页面标签的txt文件:

    public void listPageLabels(String src, String dest) throws IOException {
        // no PDF, just a text file
        PrintStream out = new PrintStream(new FileOutputStream(dest));
        PdfReader reader = new PdfReader(src);
        String[] labels = PdfPageLabels.getPageLabels(reader);
        for (int i = 0; i < labels.length; i++) {
            out.println(labels[i]);
        }
        out.flush();
        out.close();
        reader.close();
    }
    

    结果如下:

    A
    B
    1
    2
    3
    Movies-4
    Movies-5
    Movies-6
    Movies-7
    Movies-8
    

    如果你想要一个 iTextSharp 的例子,看看这个方法:

    /**
     * Reads the page labels from an existing PDF
     * @param src the existing PDF
     */
    public string ListPageLabels(byte[] src) {
        StringBuilder sb = new StringBuilder();
        String[] labels = PdfPageLabels.GetPageLabels(new PdfReader(src));
        for (int i = 0; i < labels.Length; i++) {
            sb.Append(labels[i]);
            sb.AppendLine();
        }
        return sb.ToString();
    } 
    

    更新

    正如评论部分所承诺的那样:PdfPageLabels.cs

    我不是 C# 开发人员,但这是不添加前缀的 GetPageLabels() 方法的快速而肮脏的版本:

    public static String[] GetPageLabels(PdfReader reader) {
        int n = reader.NumberOfPages;
        PdfDictionary dict = reader.Catalog;
        PdfDictionary labels = (PdfDictionary)PdfReader.GetPdfObjectRelease(dict.Get(PdfName.PAGELABELS));
        if (labels == null)
            return null;
        String[] labelstrings = new String[n];
        Dictionary<int, PdfObject> numberTree = PdfNumberTree.ReadTree(labels);    
        int pagecount = 1;
        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.S)) {
                    type = ((PdfName)d.Get(PdfName.S)).ToString()[1];
                }
                else {
                    type = 'e';
                }
            }
            switch (type) {
            default:
                labelstrings[i] = "" + pagecount;
                break;
            case 'R':
                labelstrings[i] = RomanNumberFactory.GetUpperCaseString(pagecount);
                break;
            case 'r':
                labelstrings[i] = RomanNumberFactory.GetLowerCaseString(pagecount);
                break;
            case 'A':
                labelstrings[i] = RomanAlphabetFactory.GetUpperCaseString(pagecount);
                break;
            case 'a':
                labelstrings[i] = RomanAlphabetFactory.GetLowerCaseString(pagecount);
                break;
            case 'e':
                labelstrings[i] = "";
                break;
            }
            pagecount++;
        }
        return labelstrings;
    }
    

    【讨论】:

    • GetPageLabels 函数将组合组件 PdfName.P 和 PdfName.S 以获得结果,如此处所述java-frameworks.com/csharp/itextsharp/PdfPageLabels.cs.html 因此,我在输出中收到的不仅是页码,还有 PdfName.P 组件作为前缀也。例如,请参见下图 图片:i.imgur.com/ZECFVMn.jpg 我不确定我们是否可以轻松获取罗马页码值,或者我必须执行与 GetPageLabels 相同的代码。
    • 如果有前缀,iText 会添加它,因为它是页面标签的一部分。当然,如果你不想这样,你总是可以编写一个稍微不同版本的 getPageLabels() 方法,省略前缀。 (我现在很忙,但稍后我会在我的答案中添加指向 PdfPageLabels 类的 C# 版本的链接。)
    • 感谢您的代码。让我们等待是否有更好的主意。再次感谢。
    • 我是 iText 的原始开发者。我写了PdfPageLabels 类(Java 版本)。我知道 iText(Sharp) 中没有其他方法不使用前缀 ;-)
    猜你喜欢
    • 1970-01-01
    • 2020-12-28
    • 2015-11-04
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    • 2014-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多