使用速度模板生成的 pdf 中的书签
Bookmarking in pdf generated using velocity template
我有大量数据,这些数据将用于使用速度模板生成 PDF。我有使用 .vm 文件生成的索引页,它是 table。我应该提供从索引页面到其他页面的书签。
我试过在 HTML 中只使用 href。
index.vm:
<table>
<tr>
<td>
1
</td>
<td>
<a href="#go">chapter1</a>
<td>
</tr>
</table>
assembly.vm:
<table>
<tr>
<p1 id="go">assembly1</p>
</tr>
</table>
它预计在索引页面中有 link,点击它,转到相应的内容页面。
我在从模板生成 PDF 时遇到了同样的问题,但我使用的是 JSP。每个模板引擎都是一样的逻辑。
要实现它,请在您自己的服务器上请求从 HTML 中的模板获取生成的内容,并使用 flying-saucer.
将其转换为 PDF
所以基本上你会有
根据参数返回您生成的 Velocity 模板的 servlet
(即:http://127.0.0.1/getgeneratedpdf)
dopost etc. ...
另一个 servlet 使用需要的参数调用第一个 servlet 以获取 HTML
中生成的内容
URLConnection connection = new URL(urlOfTheServletAbove).openConnection();
connection.setDoOutput(true); // POST
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
try (OutputStream output = connection.getOutputStream()) {
// parameters is encoded query string
output.write(parameters.getBytes(StandardCharsets.UTF_8));
}
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder sb = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null) { sb.append(inputLine); }
in.close();
基于 flying-saucer
的 PDF 生成器
import org.xhtmlrenderer.pdf.ITextRenderer;
// ...
private static final String TMP_DIR = System.getProperty("java.io.tmpdir");
// ...
File tempPdf = new File(TMP_DIR+tempPdfName);
if (!tempPdf.exists()) { tempPdf.createNewFile(); }
FileOutputStream fos = new FileOutputStream(tempPdf);
new ITextRenderer() {{
setDocumentFromString(sb.toString());
layout();
createPDF(fos);
}};
fos.close();
// ...
然后将PDF写入response
void writePDFContentToResponse(File pdf, HttpServletResponse response) throws IOException {
InputStream fis = new FileInputStream(pdf);
String mimeType = getServlet().getServletContext().getMimeType(pdf.getAbsolutePath());
response.setContentType(mimeType != null ? mimeType : "application/octet-stream");
response.setContentLength((int) pdf.length());
response.setHeader("Content-Disposition", "attachment; filename=yourPDFName.pdf"); // or +pdf.getName();
ServletOutputStream os = response.getOutputStream();
byte[] bufferData = new byte[1024];
int read = 0;
while((read = fis.read(bufferData)) != -1) { os.write(bufferData, 0, read); }
os.flush();
os.close();
fis.close();
response.flushBuffer();
Files.delete(pdf.toPath());
}
使用 itext 和 .vm 文件生成 pdf 后,
在生成时,将带有页码的描述存储在地图中,这是使用以下代码实现的
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("Title", "INDEX");
map.put("Action", "GoTo");
map.put("Page", String.format("%d Fit", 8));
ArrayList<HashMap<String, Object>> kids = new ArrayList<HashMap<String,Object>>();
for(BookMark book : BookMarks) {
HashMap<String, Object> kid = new HashMap<String, Object>();
kid.put("Title", book.getDescription());
kid.put("Action", "GoTo");
kid.put("Page", String.format("%d Fit", book.getPageNumber()));
ArrayList<HashMap<String, Object>> leafs = new ArrayList<HashMap<String,Object>>();
for(BookMark books : book.getLeaf()) {
HashMap<String, Object> leaf = new HashMap<String, Object>();
leaf.put("Title", books.getDescription());
leaf.put("Action", "GoTo");
leaf.put("Page", String.format("%d Fit", books.getPageNumber()));
leafs.add(leaf);
}
kid.put("Kids", leafs);
kids.add(kid);
}
map.put("Kids", kids);
ArrayList<HashMap<String, Object>> outlines = new ArrayList<HashMap<String,Object>>();
outlines.add(map);
PdfReader reader = new PdfReader(env.getProperty("path.generated.pdf").concat(fileName));
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(env.getProperty("path.generated.pdf").concat(catalogInfo.getCatalogName().trim().concat("raw1")).concat(".pdf")));
stamper.setOutlines(outlines);
stamper.setFullCompression();
stamper.close();
reader.close();
File file = new File(env.getProperty("path.generated.pdf").concat(fileName));
file.delete();
我有大量数据,这些数据将用于使用速度模板生成 PDF。我有使用 .vm 文件生成的索引页,它是 table。我应该提供从索引页面到其他页面的书签。
我试过在 HTML 中只使用 href。
index.vm:
<table>
<tr>
<td>
1
</td>
<td>
<a href="#go">chapter1</a>
<td>
</tr>
</table>
assembly.vm:
<table>
<tr>
<p1 id="go">assembly1</p>
</tr>
</table>
它预计在索引页面中有 link,点击它,转到相应的内容页面。
我在从模板生成 PDF 时遇到了同样的问题,但我使用的是 JSP。每个模板引擎都是一样的逻辑。
要实现它,请在您自己的服务器上请求从 HTML 中的模板获取生成的内容,并使用 flying-saucer.
将其转换为 PDF所以基本上你会有
根据参数返回您生成的 Velocity 模板的 servlet
(即:http://127.0.0.1/getgeneratedpdf)
dopost etc. ...
另一个 servlet 使用需要的参数调用第一个 servlet 以获取 HTML
中生成的内容 URLConnection connection = new URL(urlOfTheServletAbove).openConnection();
connection.setDoOutput(true); // POST
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
try (OutputStream output = connection.getOutputStream()) {
// parameters is encoded query string
output.write(parameters.getBytes(StandardCharsets.UTF_8));
}
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder sb = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null) { sb.append(inputLine); }
in.close();
基于 flying-saucer
的 PDF 生成器import org.xhtmlrenderer.pdf.ITextRenderer;
// ...
private static final String TMP_DIR = System.getProperty("java.io.tmpdir");
// ...
File tempPdf = new File(TMP_DIR+tempPdfName);
if (!tempPdf.exists()) { tempPdf.createNewFile(); }
FileOutputStream fos = new FileOutputStream(tempPdf);
new ITextRenderer() {{
setDocumentFromString(sb.toString());
layout();
createPDF(fos);
}};
fos.close();
// ...
然后将PDF写入response
void writePDFContentToResponse(File pdf, HttpServletResponse response) throws IOException {
InputStream fis = new FileInputStream(pdf);
String mimeType = getServlet().getServletContext().getMimeType(pdf.getAbsolutePath());
response.setContentType(mimeType != null ? mimeType : "application/octet-stream");
response.setContentLength((int) pdf.length());
response.setHeader("Content-Disposition", "attachment; filename=yourPDFName.pdf"); // or +pdf.getName();
ServletOutputStream os = response.getOutputStream();
byte[] bufferData = new byte[1024];
int read = 0;
while((read = fis.read(bufferData)) != -1) { os.write(bufferData, 0, read); }
os.flush();
os.close();
fis.close();
response.flushBuffer();
Files.delete(pdf.toPath());
}
使用 itext 和 .vm 文件生成 pdf 后, 在生成时,将带有页码的描述存储在地图中,这是使用以下代码实现的
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("Title", "INDEX");
map.put("Action", "GoTo");
map.put("Page", String.format("%d Fit", 8));
ArrayList<HashMap<String, Object>> kids = new ArrayList<HashMap<String,Object>>();
for(BookMark book : BookMarks) {
HashMap<String, Object> kid = new HashMap<String, Object>();
kid.put("Title", book.getDescription());
kid.put("Action", "GoTo");
kid.put("Page", String.format("%d Fit", book.getPageNumber()));
ArrayList<HashMap<String, Object>> leafs = new ArrayList<HashMap<String,Object>>();
for(BookMark books : book.getLeaf()) {
HashMap<String, Object> leaf = new HashMap<String, Object>();
leaf.put("Title", books.getDescription());
leaf.put("Action", "GoTo");
leaf.put("Page", String.format("%d Fit", books.getPageNumber()));
leafs.add(leaf);
}
kid.put("Kids", leafs);
kids.add(kid);
}
map.put("Kids", kids);
ArrayList<HashMap<String, Object>> outlines = new ArrayList<HashMap<String,Object>>();
outlines.add(map);
PdfReader reader = new PdfReader(env.getProperty("path.generated.pdf").concat(fileName));
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(env.getProperty("path.generated.pdf").concat(catalogInfo.getCatalogName().trim().concat("raw1")).concat(".pdf")));
stamper.setOutlines(outlines);
stamper.setFullCompression();
stamper.close();
reader.close();
File file = new File(env.getProperty("path.generated.pdf").concat(fileName));
file.delete();