Java 将页面添加为第n页
我有两个PDF文件:Java 将页面添加为第n页,java,pdf,itext,Java,Pdf,Itext,我有两个PDF文件: Master.pdf:包含带有书签、大纲(目录)的页面 Child.pdf:只有一页的文件 Child.pdf页面需要作为第n页(在我的示例中为第10页)附加到Master.pdf 生成的PDF应该为新页面提供一个新的大纲项(一个新书签)。此外,现有的书签应该可以正常工作。实际上:应该重构现有的大纲树 我可以通过iTextAPI实现这一点吗?有什么有用的样品吗 public class ConcatenateBookmarks { public static fin
public class ConcatenateBookmarks {
public static final String SRC1 = "C:\\c\\spring-in-action.pdf";
public static final String SRC2 = "C:\\c\\SPD-DUAL DS.pdf";
public static final String DEST = "C:\\c\\final.pdf";
/**
* Manipulates a PDF file src with the file dest as result
*
* @param src
* the original PDF
* @param dest
* the resulting PDF
* @throws IOException
* @throws DocumentException
*/
public void manipulatePdf(String[] src, String dest) throws IOException, DocumentException {
int POINT = 3;
Document document = new Document();
PdfSmartCopy copy = new PdfSmartCopy(document, new FileOutputStream(dest));
document.open();
PdfReader reader;
int page_offset = 0;
int n;
// Create a list for the bookmarks
ArrayList<HashMap<String, Object>> bookmarks = new ArrayList<HashMap<String, Object>>();
List<HashMap<String, Object>> tmp;
for (int i = 0; i < 1/* src.length */; i++) {
reader = new PdfReader(src[i]);
PdfReader reader2 = new PdfReader(src[1]);
int pagesCount = reader2.getNumberOfPages();
page_offset = pagesCount;
if (i == 0) {
HashMap<String, String> map = SimpleNamedDestination.getNamedDestination(reader, false);
SimpleNamedDestination.exportToXML(map, new FileOutputStream(dest), "ISO8859-1", false);
copy.addNamedDestinations(map, 0);
}
tmp = SimpleBookmark.getBookmark(reader);
// this level have to
// separate up to n don't
// change and after the
// should shift
SimpleBookmark.shiftPageNumbers(tmp, page_offset,
new int[] { POINT, reader.getNumberOfPages() + pagesCount });
bookmarks.addAll(tmp);
// add the pages
n = reader.getNumberOfPages();
page_offset += n;
for (int page = 0; page < n;) {
copy.addPage(copy.getImportedPage(reader, ++page));
if (page == POINT) // add child pages to nth point
{
for (int page2 = 0; page2 < pagesCount;) {
copy.addPage(copy.getImportedPage(reader2, ++page2));
}
}
}
copy.freeReader(reader);
reader.close();
}
// Add the merged bookmarks
copy.setOutlines(bookmarks);
// step 5
document.close();
}
/**
* Main method.
*
* @param args
* no arguments needed
* @throws DocumentException
* @throws IOException
* @throws SQLException
*/
public static void main(String[] args) throws IOException, DocumentException, SQLException {
new ConcatenateBookmarks().manipulatePdf(new String[] { SRC1, SRC2 }, DEST);
}
}
公共类连接电子书标记{
公共静态最终字符串SRC1=“C:\\C\\spring in action.pdf”;
公共静态最终字符串SRC2=“C:\\C\\SPD-DUAL DS.pdf”;
公共静态最终字符串DEST=“C:\\C\\final.pdf”;
/**
*操作PDF文件src,结果为文件dest
*
*@param src
*原始PDF
*@param dest
*生成的PDF
*@抛出异常
*@DocumentException
*/
public void manipulatedpf(String[]src,String dest)抛出IOException,DocumentException{
int点=3;
文档=新文档();
PdfSmartCopy copy=新的PdfSmartCopy(文档,新文件输出流(dest));
document.open();
PDF阅读器;
int page_offset=0;
int n;
//为书签创建一个列表
ArrayList bookmarks=新建ArrayList();
列出tmp;
对于(int i=0;i<1/*src.length*/;i++){
读卡器=新的PDF读卡器(src[i]);
PdfReader reader2=新的PdfReader(src[1]);
int pageScont=reader2.getNumberOfPages();
页面偏移量=页面浏览量;
如果(i==0){
HashMap map=SimpleNamedDestination.getNamedDestination(读取器,false);
exportToXML(映射,新文件输出流(dest),“ISO8859-1”,false);
复制.addNamedDestinations(映射,0);
}
tmp=SimpleBookmark.getBookmark(阅读器);
//这一水平必须提高
//分居到
//换衣服
//应该转移
SimpleBookmark.shiftPageNumbers(tmp,页码偏移,
新的int[]{POINT,reader.getNumberOfPages()+PageScont});
bookmarks.addAll(tmp);
//添加页面
n=reader.getNumberOfPages();
第u页偏移量+=n;
对于(int page=0;page
请看一下示例。我使用了PdfStamper
而不是PdfCopy
,但是您真正需要的代码是适应PdfOutline
的代码
在我的代码中,有一个文件名为:
我插入了一个单独的页面“Hello World”,这样它就是第4页(在您的情况下,将第4页更改为第10页),生成一个名为
插入页面是一件轻而易举的事:
PdfReader insert = new PdfReader(INSERT);
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(DEST));
stamper.insertPage(4, insert.getPageSize(1));
PdfContentByte cb = stamper.getOverContent(4);
cb.addTemplate(stamper.getImportedPage(insert, 1), 0, 0);
...
stamper.close();
最困难的问题是:如何更新大纲树?您可以从PdfReader
实例中获取大纲树,您可以创建自己的条目
,将其添加到大纲
中,然后可以使用setOutlines()
方法将更新的大纲放回PdfStamper
实例中。(您已经为PdfCopy
或PdfSmartCopy
类找到了类似的方法):
如果您的大纲是以不同的方式创建的,那么您必须调整
updateOutline()
方法,但是这个示例应该会给您足够的灵感,让您了解它是如何完成的。您必须循环浏览大纲树中的所有条目,并在适当的位置插入新的条目
。然后将新的、修改过的大纲树放回生成的PDF中。向我们展示您已经尝试过的内容。给我们看看你的密码。请原谅。现在就添加代码。谢谢布鲁诺。我试试这个,然后告诉你。非常感谢你的合作。
List<HashMap<String, Object>> outlines = SimpleBookmark.getBookmark(reader);
HashMap<String, Object> entry = new HashMap<String, Object>();
entry.put("Title", "Hello");
entry.put("Action", "GoTo");
entry.put("Page", "4 Fit");
updateOutline(outlines, entry, 4);
stamper.setOutlines(outlines);
public boolean updateOutline(List<HashMap<String, Object>> outlines, HashMap<String, Object> entry, int p) {
int index = 0;
for (HashMap<String, Object> outline : outlines) {
Object kids = outline.get("Kids");
if (kids != null) {
updateOutline((List<HashMap<String, Object>>)kids, entry, p);
}
else {
if (p < getPage(outline)) {
outlines.add(index, entry);
return true;
}
index++;
}
}
return false;
}
public int getPage(HashMap<String, Object> outline) {
Object page = outline.get("Page");
if (page == null) return -1;
String p = page.toString().substring(0, page.toString().indexOf(" "));
return Integer.parseInt(p);
}