結構イロイロ難しいね。
JasperReportsでPDFファイル作って、そのPDFファイルを結合してしおりをつける(PdfTest#mergePdf1)。
既にあるPDFファイルを結合してしおりをつける(PdfTest#mergePdf2)。
んでも、しおりのつき方によっては、うまくいかない。
というのも、しおりのつき方っていろいろあるっぽい。
ページの先頭とか、あるページの特定の箇所?ブロック?とか。
List bm = SimpleBookmark.getBookmark(pdfReader);
で得られるブックマークのリストの要素はHashMap。
MapのKeyで"Title","Action","Page"とあるけど、既にあるPDFファイルを読み込んでみると"Title"以外がなかったり。
PdfTest#mergePdf1で自前で作成したPDFファイルのブックマークは、Mapにちゃんと"Title","Action","Page"が入ってる。
とりあえず、1ページずつ作ってしおりを作っていけばいいので、PdfTest#mergePdf1な感じで要件は実現できそうだけど、いまいちブックマークのモデルというかが納得できんなぁ〜
んで、そのブックマークのリストを設定するのはsetOutlinesってなメソッド。
しおりってブックマークなんかアウトラインなんか、それともまた別のなにかなんか???
なんとなく、HTMLのAタグとNAMEタグの関係みたいなのを予想してたんだけど…
■参考サイト
iText-ページの結合
Need help with Bookmark Children when using HashMap
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import jp.co.msr.lib.util.MapUtil; import net.sf.jasperreports.engine.JRExporter; import net.sf.jasperreports.engine.JRExporterParameter; import net.sf.jasperreports.engine.JasperCompileManager; import net.sf.jasperreports.engine.JasperFillManager; import net.sf.jasperreports.engine.JasperPrint; import net.sf.jasperreports.engine.JasperReport; import net.sf.jasperreports.engine.export.JRPdfExporter; import com.lowagie.text.Document; import com.lowagie.text.pdf.PdfCopy; import com.lowagie.text.pdf.PdfCopyFields; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfPageEventHelper; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.SimpleBookmark; public class PdfTest extends PdfPageEventHelper { public static void main(String args[]) { try { createPdf(); mergePdf1(); mergePdf2(); } catch (Throwable t) { t.printStackTrace(); } } private static void createPdf() throws Throwable { JasperReport jr = JasperCompileManager.compileReport("…/template.jrxml"); List<JasperPrint> list = new ArrayList<JasperPrint>(); for ( int i = 0 ; i < 10 ; i++ ) { JRExporter exporter = new JRPdfExporter(); exporter.getParameters().put(JRExporterParameter.OUTPUT_STREAM, new FileOutputStream("…/createPdf" + String.valueOf(i) + ".pdf")); Map map = new HashMap(); map.put("value", "Test" + i); JasperPrint jp = JasperFillManager.fillReport(jr, map); exporter.setParameter(JRExporterParameter.JASPER_PRINT, jp); exporter.exportReport(); } } private static void mergePdf1() throws Throwable { OutputStream os = new FileOutputStream("…/mergePdf1.pdf"); PdfCopyFields copyFields = new PdfCopyFields(os); List bookmark = new ArrayList(); int pageOffset = 0; for ( int i = 0 ; i < 10 ; i++ ) { PdfReader pdfReader = new PdfReader(new FileInputStream("…/createPdf"+ String.valueOf(i) + ".pdf")); copyFields.addDocument(pdfReader); Map map = new HashMap(); map.put("Title", "Title " + i); map.put("Action", "GoTo"); map.put("Page", (pageOffset + 1) + " Fit"); bookmark.add(map); pageOffset = pageOffset + pdfReader.getNumberOfPages(); } copyFields.setOutlines(bookmark); copyFields.close(); os.close(); } private static void mergePdf2() throws Throwable { OutputStream os = new FileOutputStream("…/mergePdf2.pdf"); Document doc = null; PdfCopy pdf = null; List bookmark = new ArrayList(); int pageOffset = 0; for ( int i = 0 ; i < 【mergePdf2_n.pdfまで】 ; i++ ) { PdfReader pdfReader = new PdfReader(new FileInputStream("…/mergePdf2_" + String.valueOf(i) + ".pdf")); int pageCnt = pdfReader.getNumberOfPages(); if (doc == null) { doc = new Document(pdfReader.getPageSizeWithRotation(1)); pdf = new PdfCopy(doc, os); pdf.setPageEvent(new PdfTest()); doc.open(); } List bm = SimpleBookmark.getBookmark(pdfReader); if (bm != null) { shiftPageNumbers(bm, pageOffset); bookmark.addAll(bm); } pageOffset += pageCnt; for ( int j = 0 ; j < pageCnt ; j++ ) { PdfImportedPage page = pdf.getImportedPage(pdfReader, j + 1); pdf.addPage(page); } } if (bookmark.isEmpty() == false) { pdf.setOutlines(bookmark); } doc.close(); pdf.close(); os.close(); } private static void shiftPageNumbers(List bookmark, int offset) { for ( int i = 0 ; i < bookmark.size() ; i++ ) { Map map = (Map) bookmark.get(i); map.put("Action", "GoTo"); String pageFit = (String) map.get("Page"); if ((pageFit != null) && (pageFit.endsWith(" Fit") == true)) { int page = Integer.parseInt(pageFit.substring(0, (pageFit.length() - 4))); map.put("Page", (page + offset)+ " Fit"); } } } }