MangoCool

itextpdf库真的也有生成pdf的目录(index)的方法

2015-10-19 11:10:56   作者:MangoCool   来源:MangoCool

在之前开发的一个项目中,需要生成报表,因为是二次开发,考虑到兼容性和开发效率,就沿用了前辈的生成pdf文件的代码,但是事情并不是那么顺利,而这个问题也是看来不起眼,但是相当重要的,就是itextpdf库生成pdf的目录的问题。

前辈之前的做法是根据报表的固定数据量和固定格式手动添加相依的目录。那么问题来了,这样的目录,如果生成的数据和格式都可以固定和预见是完全没有问题的,否则就完全失控了,于是就有了下面的这篇文章。也算是我经历的一个比较纠结的项目,面对指定要求的客户也算是不负所托完成任务了。

对于代码没有过多的描述,看过了,再跑一跑就明了了!

依赖:jdk1.7

开发环境:ideaIU-14.1.4

测试环境:win7

建立maven工程PdfIndexDemo,在pom.xml配置文件添加必要的依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>PdfIndexDemo</groupId>
    <artifactId>PdfIndexDemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>

        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.7</version>
        </dependency>

    </dependencies>

</project>
生成pdf代码,PdfIndex.java类:
package com.mangocool.pdfindex;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by MANGOCOOL on 2015/10/19.
 */
public class PdfIndex
{

    /**
     * EventListner for Content
     */
    private static class ContentEvent extends PdfPageEventHelper
    {
        private int page;
        Map<String, Integer> index = new LinkedHashMap<String, Integer>();

        @Override
        public void onStartPage (PdfWriter writer, Document document){
            page++;
        }

        @Override
        public void onChapter (PdfWriter writer, Document document,
                               float paragraphPosition, Paragraph title){
            index.put(title.getContent(), page);
        }

        @Override
        public void onSection (PdfWriter writer, Document document,
                               float paragraphPosition, int depth, Paragraph title){
            onChapter(writer, document, paragraphPosition, title);
        }
    }

    /**
     * EventListner for Index
     */
    private static class IndexEvent extends PdfPageEventHelper
    {
        private int page;
        private boolean body;
        @Override
        public void onEndPage (PdfWriter writer, Document document)
        {
            // set page number on content
            if (body)
            {
                page++;
                ColumnText.showTextAligned(writer.getDirectContent(),
                        Element.ALIGN_CENTER, new Phrase(page + ""),
                        (document.right() + document.left()) / 2, document.bottom() - 18, 0);
            }
        }
    }

    public static void main(String[] args) throws Exception
    {
        // make content pdf (calculate page number)
        Document content = new Document(PageSize.A4, 50, 50, 50, 50);
        PdfWriter contentWriter = PdfWriter.getInstance(content, new ByteArrayOutputStream());
        ContentEvent event = new ContentEvent();
        contentWriter.setPageEvent(event);
        content.open();
        List<Chapter> chapterList = new ArrayList<Chapter>();
        for (int i = 1; i <= 10; i++)
        {
            Chunk chapTitle = new Chunk("The "+ i + " chapter");
            Chapter chapter = new Chapter(new Paragraph(chapTitle), i);
            chapTitle.setLocalDestination(chapter.getTitle().getContent());
            for (int j = 0; j < i; j++)
            {
                Chunk secTitle = new Chunk("  The " + (j + 1) + " section");
                Section section = chapter.addSection(new Paragraph(secTitle));
                secTitle.setLocalDestination(section.getTitle().getContent());
                section.setIndentationLeft(10);
                section.add(new Paragraph("mangocool mangocool " +
                                        "\nmangocool mangocool " +
                                        "\nmangocool mangocool"));
            }
            content.add(chapter);
            chapterList.add(chapter);
        }
        content.close();

        Document document = new Document(PageSize.A4, 50, 50, 50, 50);
        // add index page.
        String path = "PdfIndex.pdf";
        FileOutputStream os = new FileOutputStream(path);
        PdfWriter writer = PdfWriter.getInstance(document, os);
        IndexEvent indexEvent = new IndexEvent();
        writer.setPageEvent(indexEvent);
        document.open();
        Chapter indexChapter = new Chapter("Index:", -1);
        indexChapter.setNumberDepth(-1);// not show number style
        PdfPTable table = new PdfPTable(2);
        for (Map.Entry<String, Integer> index : event.index.entrySet())
        {
            PdfPCell left = new PdfPCell(new Phrase(index.getKey()));
            left.setBorder(Rectangle.NO_BORDER);
            Chunk pageno = new Chunk(index.getValue() + "");
            pageno.setLocalGoto(index.getKey());
            PdfPCell right = new PdfPCell(new Phrase(pageno));
            right.setHorizontalAlignment(Element.ALIGN_RIGHT);
            right.setBorder(Rectangle.NO_BORDER);
            table.addCell(left);
            table.addCell(right);
        }
        indexChapter.add(table);
        document.add(indexChapter);
        // add content chapter
        for (Chapter c : chapterList)
        {
            document.add(c);
            indexEvent.body = true;
        }
        document.close();
        os.close();
    }

}

直接运行即可,生成的PdfIndex.pdf文件,就不贴了。

文章就此结束,欢迎交流讨论!


文章来源:https://gist.github.com/kencharos/2001340

标签: itextpdf index 目录

分享:

上一篇Mina简单的入门示例

下一篇Thrift框架服务端并发处理模式的java示例

关于我

崇尚极简,热爱技术,喜欢唱歌,热衷旅行,爱好电子产品的一介码农。

座右铭

当你的才华还撑不起你的野心的时候,你就应该静下心来学习,永不止步!

人生之旅历途甚长,所争决不在一年半月,万不可因此着急失望,招精神之萎葸。

Copyright 2015- 芒果酷(mangocool.com) All rights reserved. 湘ICP备14019394号

免责声明:本网站部分文章转载其他媒体,意在为公众提供免费服务。如有信息侵犯了您的权益,可与本网站联系,本网站将尽快予以撤除。