对于java中如何从html中直接导出pdf,有很多的开源代码,这里个人用itext转。
首先需要的包有:core-renderer-1.0.jar
core-renderer-R8pre1.jar
core-renderer.jar
iText-2.0.8.jar
jtidy-4aug2000r7-dev.jar
Tidy.jar
iTextAsian.jar
java代码的话就比较简单了。具体是先用Tidy将html转换为xhtml,将xhtml转换为其它各种格式的。虽然在转化到pdf时也是用的iText。代码如下:
1. //struts1.x中
1. else if("Html2Pdf".equalsIgnoreCase(action)){
2. "http://localhost:8080/jsp/test.jsp");
3. return null;
4. }
5.
6. // 导出pdf add by huangt 2012.6.1
7. public File exportPdfFile(String urlStr) throws
8. // String outputFile = this.fileRoot + "/" +
9. // ServiceConstants.DIR_PUBINFO_EXPORT + "/" + getFileName() + ".pdf";
10. "d:/test3.pdf";
11. OutputStream os;
12. try
13. new
14.
15. new
16.
17. String str = getHtmlFile(urlStr);
18. renderer.setDocumentFromString(str);
19. ITextFontResolver fontResolver = renderer.getFontResolver();
20.
21. "C:/WINDOWS/Fonts/SimSun.ttc",BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);// 宋体字
22. "C:/WINDOWS/Fonts/Arial.ttf",BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);// 宋体字
23. renderer.layout();
24.
25. renderer.createPDF(os);
26.
27. "转换成功!");
28. os.flush();
29. os.close();
30. return new
31. catch
32. // logger.error("不存在文件!" + e.getMessage());
33. throw new
34. catch
35. // logger.error("生成pdf时出错了!" + e.getMessage());
36. throw new
37. catch
38. // logger.error("pdf出错了!" + e.getMessage());
39. throw new
40. }
41.
42. }
43.
44. // 读取页面内容 add by huangt 2012.6.1
45. public String getHtmlFile(String urlStr) throws
46. URL url;
47. try
48. if (urlStr.indexOf("?") != -1) {
49. "&locale="
50. + LocaleContextHolder.getLocale().toString();
51. else
52. "?locale="
53. + LocaleContextHolder.getLocale().toString();
54. }
55. new
56.
57. URLConnection uc = url.openConnection();
58. InputStream is = uc.getInputStream();
59.
60. new
61.
62. new
63. true); // 设定输出为xhtml(还可以输出为xml)
64. // 设定编码以正常转换中文
65. false); // 不设置它会在输出的文件中给加条meta信息
66. true); // 让它加上<?xml version="1.0"?>
67. true); // 缩进,可以省略,只是让格式看起来漂亮一些
68. tidy.parse(is, os2);
69.
70. is.close();
71.
72. // 解决乱码 --将转换后的输出流重新读取改变编码
73. String temp;
74. new
75. new BufferedReader(new
76. new
77. ((ByteArrayOutputStream) os2).toByteArray()),
78. "utf-8"));
79. while ((temp = in.readLine()) != null) {
80. sb.append(temp);
81. }
82.
83. return
84. catch
85. // logger.error("读取客户端网页文本信息时出错了" + e.getMessage());
86. throw new
87. }
88.
89. }
为了解决包的问题,加上Maven <!-- pdf导出 -->
1. <dependency>
2. <groupId>com.lowagie</groupId>
3. <artifactId>itext</artifactId>
4. <version>2.1.7</version>
5. </dependency>
6. <dependency>
7. <groupId>org.xhtmlrenderer.flyingsaucer</groupId>
8. <artifactId>pdf-renderer</artifactId>
9. <version>1.0</version>
10. </dependency>
11. <dependency>
12. <groupId>jtidy</groupId>
13. <artifactId>jtidy</artifactId>
14. <version>4aug2000r7-dev</version>
15. <type>jar</type>
16. <scope>compile</scope>
17. </dependency>
18. <dependency>
19. <groupId>net.sf.barcode4j</groupId>
20. <artifactId>barcode4j-light</artifactId>
21. <version>2.0</version>
22. </dependency>
23. <dependency>
24. <groupId>avalon-framework</groupId>
25. <artifactId>avalon-framework-impl</artifactId>
26. <version>4.2.0</version>
27. </dependency>
28. <!-- pdf -->
另外附上 稍微复杂的PDFUtils.java文件,由于没时间就不做整理解释了!
package com.iris.egrant.utils.pdf;
import java.awt.Color;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.lang.ObjectUtils;
import org.krysalis.barcode4j.impl.code128.Code128Bean;
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
import org.krysalis.barcode4j.tools.UnitConv;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import org.w3c.tidy.Configuration;
import org.w3c.tidy.Tidy;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import com.iris.egrant.exception.ServiceException;
import com.iris.egrant.file.utils.FileUtils;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.FontFactory;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Phrase;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.ColumnText;
import com.lowagie.text.pdf.PRTokeniser;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfCopy;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import com.lowagie.text.pdf.PdfWriter;
@Component
public class PDFUtil {
@Value("${fontDir}")
private String fontFileRootDir; // 字体文件路径
private final String SIMSUN = "SimSun.ttc"; // 字体-宋体
private final String SIMHEI = "SimHei.ttf"; // 字体-黑体
private final String ARIAL = "Arial.ttf"; // 字体-Arial
private final String ARIAL_B = "ArialBd.ttf"; // 字体-Arial 粗体
private final String TIMES = "Times.ttf"; // 字体-Arial
private final String TIMES_B = "TimesBd.ttf"; // 字体-Arial 粗体
private final String ARIAL_I = "ArialI.ttf"; // 字体-Arial
private final String SONGT = "SongT.ttf"; // 字体-Arial
private final String JDHEI = "JDHei.ttf"; // 字体-经典黑体加粗
private final String MSHEI = "MSHei.ttf"; // 字体-Arial
private static final String UTF8 = "UTF-8"; // 编码-UTF-8
// private static final String BARCODE_PATH = "rpt_barcode"; // 用于查找条形码的路径和文件
private static final String PDF_SUFFIX_NAME = "pdf"; // PDF后缀名(文件类型)
private static final String PIC_SUFFIX_NAME = "jpg"; // PDF后缀名(文件类型)
@Value("${pdfDir}")
private String pdfFileRootDir;// 生成PDF文件的路径
private static final Color WATERMARK_FONT_COLOR = Color.LIGHT_GRAY; // 水印字体默认颜色
private static final int WATERMARK_FONT_SIZE = 60; // 水印默认字体大小
private static final int ROTATION = 45; // 水印旋转角度
private static final String PAGETYPE = "pageType"; // 页码类型
private static final String HEADERLEFT = "headerLeft"; // 页眉位置:左 一般为图片
private static final String HEADERCENTER = "headerCenter"; // 页眉位置:中
private static final String HEADERRIGHT = "headerRight"; // 页眉位置:右
private static final String FOOTERLEFT = "footerLeft"; // 页脚位置:中
private static final String FOOTERCENTER = "footerCenter";// 页脚位置:中
private static final String FOOTERRIGHT = "footerRight";// 页脚位置:右
private static final int HEADER_Y = 35;
private static final int HEADER_LINE_Y = 40;
private static final int HEADER_LINE_X = 60;
/**
* 生成申报书条形码.
*
* @time:2012.6.13
* @author huangt
* @param code
*/
public String createBarCode(String code) throws Exception {
try {
// Create the barcode bean
Code128Bean bean = new Code128Bean();
final int dpi = 100;
// Configure the barcode generator
bean.setModuleWidth(UnitConv.in2mm(1.0f / dpi)); // makes the narrow
bean.doQuietZone(false);
// Open output file
File filePath = new File(pdfFileRootDir);
// 判断文件夹是否存在,如果不存在则创建文件夹
if (!filePath.exists()) {
filePath.mkdirs();
}
String fileName = getTempName(pdfFileRootDir, PIC_SUFFIX_NAME);
File outputFile = new File(fileName);
OutputStream out = new FileOutputStream(outputFile);
try {
// Set up the canvas provider for monochrome JPEG output
BitmapCanvasProvider canvas = new BitmapCanvasProvider(out, "image/jpeg", dpi,
BufferedImage.TYPE_BYTE_BINARY, false, 0);
// Generate the barcode
bean.generateBarcode(canvas, code);
// Signal end of generation
canvas.finish();
} finally {
out.close();
}
return fileName;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 在pdf文件中添加水印.
*
* @author huangt
* @time 2012.7.13
* @param outputFile
* 水印输出文件
* @param waterMarkName
* 水印名字
* @param rotation
* 旋转角度
*/
public void waterMark(String outputFile, String waterMarkName, int fontSize) throws Exception {
waterMark(outputFile, waterMarkName, ROTATION, WATERMARK_FONT_COLOR, fontSize, true); // 默认角度为45,默认颜色为浅灰色
}
public void waterMark(String outputFile, String waterMarkName, int fontSize, boolean isNoFirst) throws Exception {
waterMark(outputFile, waterMarkName, ROTATION, WATERMARK_FONT_COLOR, fontSize, isNoFirst); // 默认角度为45,默认颜色为浅灰色
}
public void waterMark(String outputFile, String waterMarkName) throws Exception {
waterMark(outputFile, waterMarkName, true); // 默认角度为45,默认颜色为浅灰色
}
public void waterMark(String outputFile, String waterMarkName, Color color) throws Exception {
waterMark(outputFile, waterMarkName, ROTATION, color, WATERMARK_FONT_SIZE, true); // 默认角度为45
}
public void waterMark(String outputFile, String waterMarkName, float rotation) throws Exception {
waterMark(outputFile, waterMarkName, rotation, WATERMARK_FONT_COLOR, WATERMARK_FONT_SIZE, true); // 默认颜色为浅灰色
}
public void waterMark(String outputFile, String waterMarkName, boolean isNoFirst) throws Exception {
waterMark(outputFile, waterMarkName, ROTATION, WATERMARK_FONT_COLOR, WATERMARK_FONT_SIZE, isNoFirst); // 默认角度为45,默认颜色为浅灰色
}
public void waterMark(String outputFile, String waterMarkName, float rotation, Color color, int fontSize,
boolean isNoFirst) throws Exception {
int total = 0;
String tempPdf = getTempName(pdfFileRootDir, PDF_SUFFIX_NAME);
FileUtils.copyFile(outputFile, tempPdf); // 复制一个临时文件
PdfReader reader = new PdfReader(tempPdf);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFile));
total = reader.getNumberOfPages() + 1;
PdfContentByte under;
com.lowagie.text.Font font = FontFactory.getFont(buildAbsoluteFilePath("FONT") + ARIAL, BaseFont.IDENTITY_H,
BaseFont.NOT_EMBEDDED, WATERMARK_FONT_SIZE, Font.PLAIN, color);
for (int i = 1; i < total; i++) {
if (isNoFirst && i == 1) {
continue;
}
Rectangle pageSize = reader.getPageSize(i);
under = stamper.getUnderContent(i);
under.beginText();
// 添加水印
ColumnText.showTextAligned(under, Element.ALIGN_CENTER, new Phrase(waterMarkName, font),
pageSize.getWidth() / 2, pageSize.getHeight() / 2, rotation);
under.endText();
}
stamper.close();
// 删除临时文件
deleteFile(tempPdf);// 删除临时文件
}
/**
*
* 拼接PDF (可根据所在的页码插入).
*
* @author huangt
* @time:2012.6.15
*
* */
@SuppressWarnings("unused")
private String mosaicPdf(String subfile, String outputFile, Integer index) throws Exception {
String outputFileCopy = getTempName(pdfFileRootDir, PDF_SUFFIX_NAME);
FileUtils.copyFile(outputFile, outputFileCopy); // 复制一个临时文件
String tempFile = getTempName(pdfFileRootDir, PDF_SUFFIX_NAME);
Document document = new Document();
// 建立一个书写器(Writer)与document对象关联,通过书写器(Writer)可以将文档写入到磁盘中。
PdfWriter.getInstance(document, new FileOutputStream(tempFile));
document.open();
Paragraph chunk = new Paragraph(" ");
document.add(chunk);
document.close();
PdfReader reader = new PdfReader(outputFileCopy);
PdfReader reader2 = new PdfReader(subfile);
PdfReader reader3 = new PdfReader(tempFile);
PdfStamper stamper = new PdfStamper(reader3, new FileOutputStream(outputFile));
try {
int total = reader.getNumberOfPages();
int total2 = reader2.getNumberOfPages();
PdfContentByte under;
// 从现有的别的pdf合并过来
for (int i = 1; i < total + total2; i++) {
stamper.insertPage(i, PageSize.A4);
under = stamper.getUnderContent(i);
if (i > index && i < index + total2) { // 根据index页码在PDF中插入需要插入的PDF
under.addTemplate(stamper.getImportedPage(reader2, i - index), 1, 0, 0, 1, 0, 0);
} else {
if (i >= index + total2) {
under.addTemplate(stamper.getImportedPage(reader, i - total2), 1, 0, 0, 1, 0, 0);
} else {
under.addTemplate(stamper.getImportedPage(reader, i), 1, 0, 0, 1, 0, 0);
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
stamper.close();
deleteFile(tempFile); // 删除临时文件
deleteFile(outputFileCopy);
}
return null;
}
/**
*
* 合并PDF.
*
* @author huangt
* @time:2012.6.15
* @param list
* 需要合并的PDF路径
* @param fileName
* 合并生成的PDF文件名
* */
public String mosaicPdf(List<String> list, String fileName) throws Exception {
if (list != null && list.size() > 0) {
String savePath = getFileName(pdfFileRootDir, fileName, PDF_SUFFIX_NAME);
Document document = new Document(new PdfReader(list.get(0)).getPageSize(1));
PdfCopy copy = new PdfCopy(document, new FileOutputStream(savePath));
document.open();
for (int i = 0; i < list.size(); i++) {
PdfReader reader = new PdfReader(list.get(i));
int n = reader.getNumberOfPages();
for (int j = 1; j <= n; j++) {
document.newPage();
PdfImportedPage page = copy.getImportedPage(reader, j);
copy.addPage(page);
}
}
document.close();
/*
* String savePath = getFileName(pdfFileRootDir, fileName, PDF_SUFFIX_NAME); PdfReader reader = new
* PdfReader(list.get(0)); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(savePath)); int
* total = reader.getNumberOfPages(); PdfContentByte under; int count = 0; for (String str : list) {
* PdfReader reader2 = new PdfReader(str); int total2 = reader2.getNumberOfPages() + 1; count = count +
* total2; for (int i = 1; i < total2; i++) { stamper.insertPage(count + i, PageSize.A4); under =
* stamper.getUnderContent(count + i); under.addTemplate(stamper.getImportedPage(reader2, i), 1, 0, 0, 1, 0,
* 0); } } stamper.close();
*/
for (String str : list) {
if (str.indexOf("pdf/") != -1) {
deleteFile(str);
}
}
return savePath;
} else {
return null;
}
}
/**
*
* 设置页眉和页脚.
*
* @author huangt
* @throws IOException
* @param pdfFile
* 需要设置页眉页码的pdf文件
* @param header
* 页眉内容
* @param isHomePage
* 是否首页显示页码
* @time:2012.6.15
*
* */
public void setPDFHeader(String pdfFile, Map<String, Object> header) throws IOException {
setPDFHeader(pdfFile, header, 0, true, false); // 默认首页不显示页码
}
public void setPDFHeader(String pdfFile, Map<String, Object> header, boolean isNoHomePage, boolean isNoLastPape)
throws IOException {
setPDFHeader(pdfFile, header, 0, isNoHomePage, isNoLastPape); // 默认首页不显示页码
}
/**
* 设置页眉和页脚.
*
* @param pdfFile
* 需要设置页眉页码的pdf文件
* @param header
* 页眉页脚内容
* @param isNoHomePage
* 首页是否不显示页码
* @param isNoLastPape
* 尾页是否不显示页码
* @throws IOException
*/
public void setPDFHeader(String pdfFile, Map<String, Object> header, Integer fundPages, boolean isNoHomePage,
boolean isNoLastPape) throws IOException {
int total = 0;
String tempPdf = getTempName(pdfFileRootDir, PDF_SUFFIX_NAME);
try {
FileUtils.copyFile(pdfFile, tempPdf); // 复制一个临时文件
PdfReader reader = new PdfReader(tempPdf);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(pdfFile));
total = reader.getNumberOfPages();
PdfContentByte under;
BaseFont bf = BaseFont.createFont(buildAbsoluteFilePath("FONT") + SIMHEI, BaseFont.IDENTITY_H,
BaseFont.NOT_EMBEDDED);
BaseFont bfArial = BaseFont.createFont(buildAbsoluteFilePath("FONT") + SONGT, BaseFont.IDENTITY_H,
BaseFont.NOT_EMBEDDED);
int totalNum = total; // 总页码数
if (fundPages != null) {
totalNum = totalNum - fundPages;
} else {
fundPages = 0;
}
if (isNoLastPape) { // 末页是否要页码,true 为不需要页码,则总页码减1
totalNum = totalNum - 1;
}
if (isNoHomePage) { // 首页是否要页码,true 为不需要页码,则总页码减1
totalNum = totalNum - 1;
}
String pageType = ObjectUtils.toString(header.get(PAGETYPE));
if (pageType == null || "".equals(pageType)) {
pageType = " 第 @current@ 页 共 @total@ 页 ";
}
for (int i = 1; i <= total; i++) {
// 增加内容
Rectangle pageSize = reader.getPageSize(i);
under = stamper.getUnderContent(i);
under.beginText();
if (i == 1) { // 设置版本号
if (header.containsKey("version")) {
under.setFontAndSize(bfArial, 10);
under.showTextAlignedKerned(Element.ALIGN_CENTER, ObjectUtils.toString(header.get("version")),
pageSize.getWidth() - HEADER_LINE_X - HEADER_LINE_X, HEADER_Y, 0);
}
}
under.setFontAndSize(bfArial, 9);
if (isNoHomePage) { // 判断首页是否要页码
if (i > 1) { //
if ((i - 1) <= totalNum) {
under.showTextAlignedKerned(Element.ALIGN_CENTER,
pageType.replace("@current@", (i - 1) + "").replace("@total@", totalNum + ""),
pageSize.getWidth() / 2, HEADER_Y, 0);
} else if (!isNoLastPape) {
under.showTextAlignedKerned(
Element.ALIGN_CENTER,
pageType.replace("@current@", (i - 1 - totalNum) + "").replace("@total@",
fundPages + ""), pageSize.getWidth() / 2, HEADER_Y, 0);
}
}
} else {
if (i <= totalNum) {
under.showTextAlignedKerned(Element.ALIGN_CENTER, pageType.replace("@current@", i + "")
.replace("@total@", totalNum + ""), pageSize.getWidth() / 2, HEADER_Y, 0);
} else if (!isNoHomePage) {
under.showTextAlignedKerned(Element.ALIGN_CENTER,
pageType.replace("@current@", (i - totalNum) + "").replace("@total@", fundPages + ""),
pageSize.getWidth() / 2, HEADER_Y, 0);
}
}
// 设置页眉(由于本人不知道itext能不能支持对已存在pdf修改,只能暂时用这种方法 :huangt注)
if (i > 1 && i < total) {
under.setFontAndSize(bf, 10);
setHeaderByMap(under, pageSize, header, true, true);
under.saveState();
under.setLineWidth(0.5f);
under.moveTo(50, pageSize.getHeight() - HEADER_LINE_Y);
under.lineTo(pageSize.getWidth() - 50, pageSize.getHeight() - HEADER_LINE_Y);
under.stroke();
under.restoreState();
} else {
under.setFontAndSize(bf, 10);
if (i == total) {
if (isNoLastPape) { // 如果最后一页没有页面的话
setHeaderByMap(under, pageSize, header, false, true);
} else {
setHeaderByMap(under, pageSize, header, true, true);
}
under.saveState();
under.setLineWidth(0.5f);
under.moveTo(HEADER_LINE_X, pageSize.getHeight() - HEADER_LINE_Y);
under.lineTo(pageSize.getWidth() - HEADER_LINE_X, pageSize.getHeight() - HEADER_LINE_Y);
} else if (i == 1) {
setHeaderByMap(under, pageSize, header, false, false);
under.saveState();
}
under.stroke();
under.restoreState();
}
under.endText();
}
stamper.close();
} catch (Exception e) {
e.printStackTrace();
}
// 删除临时文件
deleteFile(tempPdf);
}
/**
* 根据页眉页脚入参(位置,类型:用以@开头)设置页眉页脚.
*
* @throws IOException
* @throws MalformedURLException
* @throws DocumentException
*
* */
public void setHeaderByMap(PdfContentByte under, Rectangle pageSize, Map<String, Object> header, boolean isFoot,
boolean isHeard) throws Exception {
if (isHeard) {
String headerLeft = ObjectUtils.toString(header.get(HEADERLEFT));
String headerCenter = ObjectUtils.toString(header.get(HEADERCENTER));
String headerRight = ObjectUtils.toString(header.get(HEADERRIGHT));
// 页眉左边
if (isPath4Header(headerLeft)) {
setHeaderByImage(under, pageSize, HEADER_LINE_X, pageSize.getHeight() - HEADER_Y,
getImagePath(headerLeft));
} else {
under.showTextAlignedKerned(Element.ALIGN_LEFT, headerLeft, HEADER_LINE_X, pageSize.getHeight()
- HEADER_Y, 0);
}
// 页眉中间
if (isPath4Header(headerCenter)) {
setHeaderByImage(under, pageSize, pageSize.getWidth() / 2, pageSize.getHeight() - HEADER_Y,
getImagePath(headerCenter));
} else {
under.showTextAlignedKerned(Element.ALIGN_CENTER, headerCenter, pageSize.getWidth() / 2,
pageSize.getHeight() - HEADER_Y, 0);
}
// 页眉右边
if (isPath4Header(headerRight)) {
setHeaderByImage(under, pageSize, pageSize.getWidth() - HEADER_LINE_X, pageSize.getHeight() - HEADER_Y,
getImagePath(headerRight), true);
} else {
under.showTextAlignedKerned(Element.ALIGN_RIGHT, headerRight, pageSize.getWidth() - HEADER_LINE_X,
pageSize.getHeight() - HEADER_Y, 0);
}
}
if (isFoot) {
String footerLeft = ObjectUtils.toString(header.get(FOOTERLEFT));
String footerCenter = ObjectUtils.toString(header.get(FOOTERCENTER));
String footerRight = ObjectUtils.toString(header.get(FOOTERRIGHT));
// 页脚左边
if (isPath4Header(footerLeft)) {
setHeaderByImage(under, pageSize, HEADER_LINE_X, HEADER_Y, getImagePath(footerLeft));
} else {
under.showTextAlignedKerned(Element.ALIGN_LEFT, footerLeft, HEADER_LINE_X, HEADER_Y, 0);
}
// 页脚中间
if (isPath4Header(footerCenter)) {
setHeaderByImage(under, pageSize, pageSize.getWidth() / 2, HEADER_Y, getImagePath(footerCenter));
} else {
under.showTextAlignedKerned(Element.ALIGN_CENTER, footerCenter, pageSize.getWidth() / 2, HEADER_Y, 0);
}
// 页脚右边
if (isPath4Header(footerRight)) {
setHeaderByImage(under, pageSize, pageSize.getWidth() - HEADER_LINE_X, HEADER_Y,
getImagePath(footerRight), true);
} else {
under.showTextAlignedKerned(Element.ALIGN_RIGHT, footerRight, pageSize.getWidth() - HEADER_LINE_X,
HEADER_Y, 0);
}
}
}
public void setHeaderByImage(PdfContentByte under, Rectangle pageSize, float x, float y, String imagePath)
throws Exception {
if (imagePath != null && !"".equals(imagePath)) {
Image image = Image.getInstance(imagePath);
image.setAbsolutePosition(x, y);
under.addImage(image);
}
}
public void setHeaderByImage(PdfContentByte under, Rectangle pageSize, float x, float y, String imagePath,
boolean isRight) throws Exception { // 右边的图片需要减去图片的宽度
if (imagePath != null && !"".equals(imagePath)) {
Image image = Image.getInstance(imagePath);
if (isRight) {
image.setAbsolutePosition(x - image.getWidth(), y);
} else {
image.setAbsolutePosition(x, y);
}
under.addImage(image);
}
}
/**
* 页眉页脚插入图时,判断是否是图片路径,并返回图片的路径(因为传过来的值是以@开头的为路径).
*
* */
public boolean isPath4Header(String headerStr) {
if (headerStr.startsWith("@")) {
return true;
}
return false;
}
public String getImagePath(String headerStr) {
return headerStr.substring(1);
}
/**
* 生成PDF.
*
* @param urlStr
* 要生成PDF的页面URL
* @param map
* 页面需要用到的参数
* @return
* @throws Exception
*/
public String exportPdfFile(String urlStr, Map<String, Object> map) throws Exception {
String outputFile = getTempName(pdfFileRootDir, PDF_SUFFIX_NAME);
File filePath = new File(pdfFileRootDir);
// urlStr = URLDecoder.decode(urlStr, "UTF-8");
if (!filePath.exists()) {
filePath.mkdirs();
}
OutputStream os;
try {
os = new FileOutputStream(outputFile);
ITextRenderer renderer = new ITextRenderer();
String str = getHtmlFile(urlStr, map);
// renderer.setDocument(new File(str));
renderer.setDocumentFromString(str);
ITextFontResolver fontResolver = renderer.getFontResolver();
fontResolver.addFont(buildAbsoluteFilePath("FONT") + SIMSUN, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); // 字体包
fontResolver.addFont(buildAbsoluteFilePath("FONT") + SIMHEI, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); // 黑体
fontResolver.addFont(buildAbsoluteFilePath("FONT") + ARIAL, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); // Arail
fontResolver.addFont(buildAbsoluteFilePath("FONT") + ARIAL_B, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); // Arail
fontResolver.addFont(buildAbsoluteFilePath("FONT") + ARIAL_I, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); // Arail
// Times New Roman
fontResolver.addFont(buildAbsoluteFilePath("FONT") + TIMES, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
// Times New Roman
fontResolver.addFont(buildAbsoluteFilePath("FONT") + TIMES_B, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
fontResolver.addFont(buildAbsoluteFilePath("FONT") + JDHEI, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
fontResolver.addFont(buildAbsoluteFilePath("FONT") + MSHEI, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
renderer.layout();
renderer.createPDF(os);
os.flush();
os.close();
// 返回生成PDF文件的路径和名字 ,以保存数据库
return outputFile;
} catch (FileNotFoundException e) {
// logger.error("不存在文件!" + e.getMessage());
throw new ServiceException(e);
} catch (DocumentException e) {
// logger.error("生成pdf时出错了!" + e.getMessage());
throw new ServiceException(e);
} catch (IOException e) {
// logger.error("pdf出错了!" + e.getMessage());
throw new ServiceException(e);
}
}
// 读取页面内容 add by huangt 2012.6.1
public static String getHtmlFile(String urlStr, Map<String, Object> map) throws ServiceException {
URL url;
try {
if (urlStr.indexOf("?") != -1) {
urlStr = urlStr + "&locale=" + LocaleContextHolder.getLocale().toString();
} else {
urlStr = urlStr + "?locale=" + LocaleContextHolder.getLocale().toString();
}
url = new URL(urlStr);
// URLConnection uc = url.openConnection();
// uc.addRequestProperty("xmlData", xmlData);
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
// 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在http正文内,因此需要设为true,
// 默认情况下是false;
urlConn.setDoOutput(true);
// 设置是否从httpUrlConnection读入,默认情况下是true;
urlConn.setDoInput(true);
// Post 请求不能使用缓存
urlConn.setUseCaches(false);
// 设定传送的内容类型是可序列化的java对象
// (如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)
// 设定请求的方法为"POST",默认是GET
urlConn.setRequestMethod("POST");
// 连接,上面对urlConn的所有配置必须要在connect之前完成,
urlConn.connect();
// 此处getOutputStream会隐含的进行connect (即:如同调用上面的connect()方法,
// 所以在开发中不调用上述的connect()也可以)。
OutputStream os = urlConn.getOutputStream();
String param = new String();
String xmlData = URLEncoder.encode(map.get("xmlData").toString(), "UTF-8");
if (map.containsKey("barCodePath")) {
param = "xmlData=" + xmlData + "&jspUrl=" + map.get("jspUrl").toString() + "&barCodePath="
+ map.get("barCodePath"); // 传参
} else {
param = "xmlData=" + xmlData + "&jspUrl=" + map.get("jspUrl").toString(); // 传参
}
os.write(param.getBytes());
InputStream is = urlConn.getInputStream();
Tidy tidy = new Tidy();
OutputStream os2 = new ByteArrayOutputStream();
tidy.setXHTML(true); // 设定输出为xhtml(还可以输出为xml)
tidy.setCharEncoding(Configuration.UTF8); // 设定编码以正常转换中文
tidy.setTidyMark(false); // 不设置它会在输出的文件中给加条meta信息
tidy.setXmlPi(true); // 让它加上<?xml version="1.0"?>
tidy.setIndentContent(true); // 缩进,可以省略,只是让格式看起来漂亮一些
tidy.parse(is, os2);
is.close();
// 解决乱码 --将转换后的输出流重新读取改变编码
String temp;
StringBuffer sb = new StringBuffer();
BufferedReader in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(
((ByteArrayOutputStream) os2).toByteArray()), UTF8));
while ((temp = in.readLine()) != null) {
sb.append(temp);
}
return sb.toString();
} catch (IOException e) {
// logger.error("读取客户端网页文本信息时出错了" + e.getMessage());
throw new ServiceException(e);
}
}
/**
*
* 根据特殊字符查找所在页码.
*
* @author huangt
* @throws IOException
* @time:2012.7.6
*
* */
public static int findStringForPageNum(String fileName, String pageString) throws Exception {
// String PAGESTRING = "#$%@*";
PdfReader reader = new PdfReader(fileName);
int pageNum = 0;
int total = reader.getNumberOfPages();
String pageStringUnicode = toUnicode(pageString);
for (int i = 1; i < total; i++) {
byte[] streamBytes = reader.getPageContent(i);
PRTokeniser tokenizer = new PRTokeniser(streamBytes);
StringBuffer sb = new StringBuffer();
while (tokenizer.nextToken()) {
if (tokenizer.getTokenType() == PRTokeniser.TK_STRING) {
String temp;
System.out.println(tokenizer.getStringValue());
byte[] b = tokenizer.getStringValue().getBytes("ISO-8859-1");
for (int j = 0; j < b.length; j++) {
temp = Integer.toHexString(0xFF & b[j]);
if (temp.length() < 2) {
sb.append(0);
}
sb.append(temp);
}
}
}
if (sb.toString().indexOf(pageStringUnicode) > 0) {
pageNum = i;
break;
}
}
return pageNum;
}
/**
* 删除临时文件 fileName:如果传入文件名,即不生成序列化的临时文件名.
* */
public static void deleteFile(String fileName) {
File file = new File(fileName);
file.delete();
}
/**
* 生成序列化的临时文件名 fileDir:文件路径 type:文件类型,如jpg pdf 等 fileName:如果传入文件名,即不生成序列化的临时文件名.
* */
public static String getTempName(String fileDir, String type) {
String fileStr = fileDir + UUID.randomUUID().toString() + "." + type;
return fileStr;
}
/**
* 生成文件名 fileDir:文件路径 type:文件类型,如jpg pdf 等 fileName:如果传入文件名,即不生成序列化的临时文件名.
* */
public static String getFileName(String fileDir, String fileName, String type) {
String fileStr = fileDir + fileName + "." + type;
return fileStr;
}
public static void parsePdf(String src) throws IOException {
PdfReader reader = new PdfReader(src);
byte[] streamBytes = reader.getPageContent(1);
PRTokeniser tokenizer = new PRTokeniser(streamBytes);
while (tokenizer.nextToken()) {
if (tokenizer.getTokenType() == PRTokeniser.TK_STRING) {
StringBuffer sb = new StringBuffer();
String sTemp;
for (int i = 0; i < tokenizer.getStringValue().getBytes("Unicode").length; i++) {
sTemp = Integer.toHexString(0xFF & tokenizer.getStringValue().getBytes("Unicode")[i]);
if (sTemp.length() < 2) {
sb.append(0);
}
sb.append(sTemp);
}
System.out.println(sb.toString());
}
}
}
public static String toUnicode(String s) throws Exception {
byte[] bytes = s.getBytes("Unicode");
String str;
StringBuffer sb = new StringBuffer();
for (int j = 2; j < bytes.length; j++) {
str = Integer.toHexString(0xFF & bytes[j]);
if (str.length() < 2) {
sb.append(0);
}
sb.append(str);
}
return sb.toString();
}
private String buildAbsoluteFilePath(String type) {
String apath = "";
if ("PDF".equalsIgnoreCase(type)) {
apath = pdfFileRootDir;
}
if ("FONT".equalsIgnoreCase(type)) {
apath = fontFileRootDir;
}
// if (!apath.endsWith(File.separator)) {
// apath += File.separator;
// }
return apath;
}
}