生成一个带有目录(可跳转)的pdf文件(支持中文).




import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.kernel.pdf.action.PdfAction;
import com.itextpdf.kernel.pdf.canvas.draw.DottedLine;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Tab;
import com.itextpdf.layout.element.TabStop;
import com.itextpdf.layout.element.Text;
import com.itextpdf.layout.property.Property;
import com.itextpdf.layout.property.TabAlignment;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.text.pdf.BaseFont;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;

/**
 * @date 2019/9/3 18:54
 */
public class PDF {

    // 字体为宋体
    private static final String PDFTYPEFACE = "pdfTypeface/simsun.ttf";

    /**
     * 生成一个带有目录(可跳转)的pdf文件(支持中文).
     * 如果目录两页,请为pdf多留出一页空白内容.
     * 此方法不能生成书签.
     *
     * @param sourceFile      源pdf文件
     * @param targetFile      带有目录(可跳转)的pdf文件
     * @param catalogs        目录数据map<标题,页码>
     * @param catalogTitle    目录上方第一行文字
     * @param catalogPageSize 目录占页大小(为锚点偏移做参数)
     * @return targetFile
     * @throws IOException
     */
    public static String createPdfWithCatalog(String sourceFile, String targetFile, String catalogTitle,
                                              Map<String, Integer> catalogs, int catalogPageSize) throws IOException {
        Map<String, Integer> catalogsTemp = new TreeMap<>();
        catalogsTemp.putAll(catalogs);
        //实际页码索引偏移量为 目录占页数-1
        int offset = catalogPageSize - 1;
        for (Map.Entry<String, Integer> entry : catalogsTemp.entrySet()) {
            entry.setValue(entry.getValue() + offset);
        }

        File file = new File(targetFile);
        file.getParentFile().mkdirs();
        PdfWriter pdfWriter = new PdfWriter(targetFile);
        PdfDocument pdfDoc = new PdfDocument(pdfWriter);
        Document document = new Document(pdfDoc);
        PdfFont font0 = PdfFontFactory.createFont(PDFTYPEFACE, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        if (catalogTitle == null) {
            catalogTitle = " ";
        }
        document.add(new Paragraph(new Text(catalogTitle))
                .setTextAlignment(TextAlignment.CENTER).setFont(font0));
        PdfDocument firstSourcePdf = new PdfDocument(new PdfReader(sourceFile));
        int numberOfPages = firstSourcePdf.getNumberOfPages();
        for (int i = 1; i <= numberOfPages; i++) {
            PdfPage page = firstSourcePdf.getPage(i).copyTo(pdfDoc);
            pdfDoc.addPage(page);
            for (Map.Entry<String, Integer> entry : catalogsTemp.entrySet()) {
                if (i == entry.getValue()) {
                    String destinationKey = "p" + (pdfDoc.getNumberOfPages() - 1);
                    PdfArray destinationArray = new PdfArray();
                    destinationArray.add(page.getPdfObject());
                    destinationArray.add(PdfName.XYZ);
                    destinationArray.add(new PdfNumber(0));
                    destinationArray.add(new PdfNumber(page.getMediaBox().getHeight()));
                    destinationArray.add(new PdfNumber(1));
                    try {
                        pdfDoc.addNamedDestination(destinationKey, destinationArray);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    Paragraph p = new Paragraph();
                    PdfFont font = PdfFontFactory.createFont(PDFTYPEFACE, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                    p.setFont(font);
                    p.addTabStops(new TabStop(540, TabAlignment.RIGHT, new DottedLine()));
                    p.add(entry.getKey());
                    p.add(new Tab());
                    p.add(String.valueOf(pdfDoc.getNumberOfPages() - 1));
                    p.setProperty(Property.ACTION, PdfAction.createGoTo(destinationKey));
                    document.add(p);
                }
            }
        }
        firstSourcePdf.close();
        document.close();
        return targetFile;
    }


}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在ReportLab中生成带有侧边栏书签跳转PDF电子书需要几个步骤: 1. 安装ReportLab库和PyPDF2库。 2. 在需要添加书签的地方使用`pdf.addOutline()`函数添加书签,该函数需要一个包含书签名称和页码的字典作为参数。 3. 使用`pdf.save()`函数保存生成PDF文件。 下面是一个简单的例子,展示了如何在ReportLab中生成带有书签跳转PDF电子书: ```python from reportlab.lib.pagesizes import letter from reportlab.pdfgen import canvas from PyPDF2 import PdfFileWriter, PdfFileReader # Create a new PDF with Reportlab c = canvas.Canvas("bookmarks.pdf", pagesize=letter) # Draw things on the PDF. Here's where the PDF generation happens. # See the ReportLab documentation for the full list of functionality. c.drawString(100, 100, "Chapter 1") c.showPage() c.drawString(100, 100, "Chapter 2") c.showPage() c.save() # Create a PDF object, using the file object as its "file." pdf = PdfFileReader(open("bookmarks.pdf", "rb")) # Create a PDF outline pdf.addOutline({'Title': 'Chapter 1', 'Page': 1}) pdf.addOutline({'Title': 'Chapter 2', 'Page': 2}) # Save the new pdf output = PdfFileWriter() output.addPage(pdf.getPage(0)) output.addPage(pdf.getPage(1)) output.write(open("bookmarks_with_outline.pdf", "wb")) ``` 这样就生成一个名为"bookmarks_with_outline.pdf"的带有侧边栏书签跳转的电子书了。 ### 回答2: 在reortlab中生成一个带有侧边栏书签跳转PDF电子书,我们需要遵循以下步骤: 1. 导入所需的库和模块: ``` from reportlab.lib.pagesizes import letter from reportlab.lib.enums import TA_CENTER from reportlab.pdfgen.canvas import Canvas from reportlab.platypus import TableOfContents, Paragraph, SimpleDocTemplate, \ Spacer, PageBreak, Frame, KeepInFrame from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle, \ ListStyle, ListItem ``` 2. 创建一个包含目录的数据结构: ``` story = [] toc = TableOfContents() toc.levelStyles = [ParagraphStyle(fontName='Helvetica-Bold', fontSize=16, name='Heading1', spaceAfter=10)] story.append(toc) story.append(PageBreak()) ``` 3. 设置样式: ``` styles = getSampleStyleSheet() title_style = styles['Title'] heading1_style = styles['Heading1'] body_style = styles['BodyText'] ``` 4. 添加章节和内容: ``` # 添加章节标题 story.append(Paragraph('章节一', heading1_style)) # 添加内容 story.append(Paragraph('这是章节一的内容。', body_style)) # 添加目录条目(书签跳转) toc.addEntry('章节一', 0, 1) ``` 5. 创建PDF文档: ``` doc = SimpleDocTemplate("book.pdf", pagesize=letter) # 将故事(章节和内容)添加到文档中 doc.build(story) ``` 通过以上步骤,我们可以在生成PDF电子书中看到侧边栏的书签,并且点击书签可以跳转到相应的章节内容。这样的PDF电子书非常适合用于创建可导航的文档或电子书。 ### 回答3: 在reortlab中生成一个带有侧边栏书签跳转pdf电子书,可以按照以下步骤操作: 1.首先,在LaTeX中使用reortlab文档类创建一个新的.tex文件。 2.在导言区,使用相关的包,如`\usepackage{hyperref}`来引入hyperref宏包,它可以帮助我们创建书签。 3.在正文区域,书写内容,并按照需要添加章节、子章节以及其他标题。 4.在需要添加书签的地方,使用`\section{}`、`\subsection{}`等命令来创建相应的章节。例如,`\section{Introduction}`。 5.在`\begin{document}`和`\end{document}`之间,使用`\tableofcontents`命令来生成目录。 6.接下来,使用`\phantomsection`命令来标记书签链接的位置。例如,`\phantomsection \label{bookmark}`。 7.在书签所在的位置,使用`\hypertarget{bookmark}`命令来设置书签。 8.在需要书签跳转的位置,使用`\hyperlink{bookmark}{text}`命令来创建跳转链接,其中`bookmark`是之前设置的书签名称,`text`为显示的文本。 9.完成以上设置后,使用编译器(如Texmaker等)进行编译生成PDF文件。 10.打开生成PDF文件,你将看到在侧边栏上显示了书签。 11.点击这些书签,可以跳转到你之前设置的相应位置。 通过以上步骤,你就可以在reortlab中生成一个带有侧边栏书签跳转pdf电子书。这样的电子书对于读者阅读和导航来说非常方便,可以快速跳转到感兴趣的章节或内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值