最近要用到导出PDF,看了网上例子,很快导出来了,但是遇到了中文无法显示,水印被覆盖等等问题,最后还是搜罗了很多代码解决了,在此记录一下;另外,网上很多代码都执行无效 --
1使用ITextRenderer导出PDF
public class PdfOld {
protected static Log logger = LogFactory.getLog(PdfOld.class);
/**
*
* @param htmlFile html文件存储路径
* @param pdfFile 生成的pdf文件存储路径
* @param chineseFontPath 中文字体存储路径
*/
public static void html2pdf(String htmlFile, String pdfFile, String chineseFontPath) {
String url;
OutputStream os = null;
try {
url = new File(htmlFile).toURI().toURL().toString();
os = new FileOutputStream(pdfFile);
ITextRenderer renderer = new ITextRenderer();
System.out.println(url);
renderer.setDocument(url);
// 解决中文不显示问题
ITextFontResolver fontResolver = renderer.getFontResolver();
fontResolver.addFont(chineseFontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
renderer.layout();
renderer.createPDF(os);
} catch (Exception e) {
logger.warn(e.toString(), e);
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
logger.warn(e.toString(), e);
}
}
}
}
public static void main(String[] args) {
try {
//html文件路径
String htmlFilePath = "C:\\Users\\Administrator\\Desktop\\PDFHTML.html";
// 中文字体存储路径
String chineseFontPath = "F:\\simsun.ttf";
// html转pdf
html2pdf(htmlFilePath, "C:\\Users\\Administrator\\Desktop\\index.pdf", chineseFontPath);
System.out.println("转换成功!");
} catch (Exception e) {
logger.error("html转换为pdf失败", e);
}
}
这种方式无法带水印
2 使用PdfWriter
private static BaseFont bfChinese;
public static void main(String[] args) throws Exception {
String templatePath="C:\\Users\\Administrator\\Desktop\\PDFHTML.html";
String targetPath="C:\\Users\\Administrator\\Desktop\\target.pdf";
String waterUmagePath="C:\\Users\\Administrator\\Desktop\\test.png";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
String waterName = simpleDateFormat.format(new Date()) + "1122334";
createPdfWithMark(templatePath, targetPath, waterName, waterUmagePath);
}
public static void createPdfWithMark(String htmlFile, String targetUrl, String waterName, String markPicUrl) throws Exception {
String html = createHtmlFromFile(htmlFile);
String tempPdfPath = "C:\\Users\\timeless\\Desktop\\"+Thread.currentThread().getId()+"temp.pdf";
createTempPdfFromHtml(html, tempPdfPath);
addPdfMark(tempPdfPath, targetUrl, waterName, markPicUrl);
}
public static String createHtmlFromFile(String htmlFile) throws Exception {
BufferedInputStream in = null;
StringBuilder templatecontent = new StringBuilder();
try {
File file = new File(htmlFile);
in = new BufferedInputStream(new FileInputStream(file));
byte[] bytes = new byte[1024];
int len;
while((len = in.read(bytes)) != -1) {
templatecontent.append(new String(bytes, 0, len, "utf-8"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(null != in) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return templatecontent.toString();
}
public static void createTempPdfFromHtml(String html, String tempPdfPath) throws Exception {
List parseToList = HTMLWorker.parseToList(new StringReader(html), null, new HashMap());
Document d = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.getInstance(d, new FileOutputStream(new File(tempPdfPath)));
d.open();
for (Element e : parseToList) {
fixChineseCoding(e);
d.add(e);
}
d.close();
}
public static void addPdfMark(String InPdfFile, String outPdfFile, String waterMarkName, String markImagePath) throws Exception {
PdfReader reader = new PdfReader(InPdfFile);
PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(outPdfFile));
BaseFont base = BaseFont.createFont(PDFUtils.class.getClassLoader().getResource("simsun.ttf").getFile(), "Identity-H", true);
int j = waterMarkName.length();
char c = 0;
int rise = 0;
int total = reader.getNumberOfPages() + 1;
for (int i = 1; i < total; i++) {
rise = 500;
PdfContentByte under = stamp.getOverContent(i);//水印上层 underContent下层
under.beginText();
under.setFontAndSize(base, 30);
under.setColorFill(BaseColor.LIGHT_GRAY);
if (j >= 15) {
under.setTextMatrix(30, 250);
for (int k = 0; k < j; k++) {
under.setTextRise(rise);
c = waterMarkName.charAt(k);
under.showText(c + "");
rise -= 6;
}
} else {
under.setTextMatrix(300, 100);
for (int k = 0; k < j; k++) {
under.setTextRise(rise);
c = waterMarkName.charAt(k);
under.showText(c + "");
rise -= 6;
}
}
under.endText();
if (StringUtils.isNotBlank(markImagePath)) {
Image image = Image.getInstance(markImagePath);
image.setAbsolutePosition(50, 50);
under.addImage(image);
}
}
stamp.close();
File tempfile = new File(InPdfFile);
if (tempfile.exists()) {
tempfile.delete();
}
}
private static void fixChineseCoding(Element e) throws IOException, DocumentException {
if (bfChinese == null) {
bfChinese = BaseFont.createFont(PDFUtils.class.getClassLoader().getResource("simsun.ttf").getFile(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
}
//解决中文乱码
if (e instanceof Paragraph) {
for (Chunk c : e.getChunks()) {
Font cfont = new Font(bfChinese, 20, Font.NORMAL);
cfont.setColor(c.getFont().getColor());
cfont.setSize(c.getFont().getSize());
c.setFont(cfont);
}
return;
}
if (e instanceof PdfPTable) {
PdfPTable table = (PdfPTable)e;
for (PdfPRow row : table.getRows()) {
for (PdfPCell cell : row.getCells()) {
if(cell!=null && cell.getCompositeElements() != null) {
for(Element comp : cell.getCompositeElements()) {
fixChineseCoding(comp);
}
}
}
}
}
}