码迷,mamicode.com
首页 > 编程语言 > 详细

Java将HTML导出为PDF

时间:2017-10-22 23:42:55      阅读:489      评论:0      收藏:0      [点我收藏+]

标签:文本   输出   exception   记录   shm   header   编码   info   eth   

 


大纲内容:

  1. 配置对应jar

  2. 编写HTML模板

  3. 编写导出PDF工具类

  4. 业务中调用PDF工具类


  1. 背景

市场上Java导出wordexecl较多,比如POI等。反而Java导出PDF实现开源的少之又少。为了防止用户修改自己公司定制的一些文件,因此将一些数据导出PDF,以便用户阅读。对于Java导出PDF,市场上主要有:1.iText实现HTML2PDF,速度快、纠错能力差、支持中文、只支持Unicode编码,一种中文格式,样式单一,开源。2.Flying Ssauser实现HTML2PDF,纠错能力差、支持多种中文字体,部分样式不支持(css3中的部分样式不支持),开源。3.速度快,纠错能力强,支持多种中文字体,商业不开源。

结合市场上的JavaHTML导出PDF开源,都不符合自己需求。因此,自己综合市场的技术,自己采用Flying Ssauser实现导出PDF定制开发。


  1. 配置maven依赖

现在JavaEE开发都是采用maven项目,方便jar管理和维护。开发JavaHTML导出PDF所需要的jar,在pom.xml文件中配置如下:

<!-- https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-pdf-itext5 -->

<dependency>

<groupId>org.xhtmlrenderer</groupId>

<artifactId>flying-saucer-pdf-itext5</artifactId>

</dependency>


  1. 编写HTML模板

template.html代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>PDF 模版</title>

<style type="text/css">

body{

font-family:SimSun;

font-size:14px;

}

.line{

border-bottom:1px solid #151716;

margin-top:3px;

}

.titleContent{

margin-top:20px;

}

.tabtitle{

background-color:#1184CE;

color:#FFFFFF;

height:20px;

padding-left:10px;

padding-top:3px;

 

}

.listtitle{

background-color:#1184CE;

color:#FFFFFF;

padding-top:20px;

padding-left:20px;

padding-right:15px;

-moz-border-radius: 15px; /* Gecko browsers */

-webkit-border-radius: 15px; /* Webkit browsers */

border-radius:15px; /* W3C syntax */

}

.img{

padding-left:40px;

}

.oneTitle{

color:#1184CE;

font-size:26px;

}

.colTitle{

color:#1184CE;

}

.totalProject{

background-color:#1184CE;

color:#FFFFFF;

text-align:center;

margin-top:40px;

height:22px;

padding-top:5px;

}

@page {

size: 8.5in 11in;

@top-center{

content: element(pageHeader);

}

@bottom-center {

content: counter(page) " / " counter(pages);

}

}

 

#pageHeader{

position: running(pageHeader);

}

</style>

</head>


<body>

<div class="showMain" style="page-break-after:inherit;">

<div id="pageHeader">

<div align="center">xxxxxxx股份有限公司电话:023-666666</div>

<div class="line"></div>

</div>

<div class="titleContent">

<table border="0">

<tr>

<td width="414" height="113" class="listtitle">

<span style="font-size:26px;">###useType###</span><br/>

<span>买方名称:###oName###</span><br/>

<span>报价单日期:###gmtModified###</span><br/>

<span style="float:right;">NO:###orderId###</span>

</td>

<td ><img src="###imgsrc###" height="113" class="img" /></td>

</tr>

</table>

</div>

<div>

<p class="oneTitle">1.报价单描述</p>

</div>

<div class="cardTerminal">

<p class="tabtitle">xxxxx采集终端</p>

<div class="termianlTab">

<table border="0" >

<tr class="colTitle">

<td width="435">名称</td>

<td width="70">数量</td>

<td width="105">单价</td>

<td width="342">金额</td>

</tr>

###trBox###

</table>

</div>

<div class="line"></div>

<div style="float:right;margin-top:10px;">总价:¥###boxPrice###</div>

</div>

###divProduct###

<div class="totalProject" >项目总价:¥###projectPrice###</div>

<div style="padding-top:20px;width:100%">

<p class="oneTitle">2.清单备注</p>

<p>&nbsp;&nbsp;###description###</p>

</div>

</div>

</body>

</html>


首先,动态变更的数据用字符串变量取代,在Java后台进行替换。其次,对于PDF的分页,在HTML模板中,采用css3@page进行分页操作。再次,HTML模板中的字体采用window字体库中英文的宋体字体。


  1. 编写导出PDF工具类

  1. PDF工具类代码:

package com.wxh.utils;


import java.io.OutputStream;

import java.text.DecimalFormat;

import java.util.List;


import javax.servlet.http.HttpServletResponse;


import com.wxh.model.OrderInfo;

import com.lowagie.text.Chunk;

import com.lowagie.text.Document;

import com.lowagie.text.Element;

import com.lowagie.text.Font;

import com.lowagie.text.HeaderFooter;

import com.lowagie.text.PageSize;

import com.lowagie.text.Paragraph;

import com.lowagie.text.Phrase;

import com.lowagie.text.pdf.BaseFont;

import com.lowagie.text.pdf.PdfPCell;

import com.lowagie.text.pdf.PdfPTable;

import com.lowagie.text.pdf.PdfWriter;


public class PDFUtil {


public static Font headfont; // 设置头部字体大小

public static Font keyfont; // 设置标题字体大小

public static Font textfont; // 设置文本字体大小


// static int maxWidth = 520;


static {

BaseFont bfChinese;

try {

// bfChinese = BaseFont.createFont("C:/windows/fonts/simsun.ttc,1", BaseFont.IDENTITY_H,

// BaseFont.EMBEDDED);

String url = PDFUtil.class.getResource("").getPath().replaceAll("%20", " ");

String path = url.substring(0, url.indexOf("WEB-INF")) + "WEB-INF/config/font/";

//jar包中的class文件调用这个接口时返回的path"file:"开头,这里需调用外部的资源文件,所以需要删除file:

if (path.startsWith("file")) {

path = path.substring(5);

}

bfChinese = BaseFont.createFont(path + "/simsun.ttc,1", BaseFont.IDENTITY_H,

BaseFont.EMBEDDED);

headfont = new Font(bfChinese, 10, Font.BOLD);// 设置头部字体大小、还可以设置颜色如:Color.BLUE

keyfont = new Font(bfChinese, 8, Font.BOLD);// 设置标题字体大小

textfont = new Font(bfChinese, 8, Font.NORMAL);// 设置文本字体大小

} catch (Exception e) {

e.printStackTrace();

}

}


/**

* 创建单元格,设置值、字体、对齐方式

*

* @param value

* @param font

* @param align

* @return

*/

public static PdfPCell createCell(String value, com.lowagie.text.Font font, int align) {

PdfPCell cell = new PdfPCell();

cell.setVerticalAlignment(Element.ALIGN_MIDDLE);

cell.setHorizontalAlignment(align);

cell.setPhrase(new Phrase(value, font));

return cell;

}


/**

* 创建单元格,设置值、字体

*

* @param value

* @param font

* @return

*/

public static PdfPCell createCell(String value, com.lowagie.text.Font font) {

PdfPCell cell = new PdfPCell();

cell.setVerticalAlignment(Element.ALIGN_MIDDLE);

cell.setHorizontalAlignment(Element.ALIGN_CENTER);

cell.setPhrase(new Phrase(value, font));

return cell;

}


/**

* 创建单元格,设置值、字体、对齐方式、合并列

*

* @param value

* @param font

* @param align

* @param colspan

* @return

*/

public static PdfPCell createCell(String value, com.lowagie.text.Font font, int align,

int colspan) {

PdfPCell cell = new PdfPCell();

cell.setVerticalAlignment(Element.ALIGN_MIDDLE);

cell.setHorizontalAlignment(align);

cell.setColspan(colspan);

cell.setPhrase(new Phrase(value, font));

return cell;

}


/**

* 创建单元格,设置值、字体、对齐方式、合并列、边框

*

* @param value

* @param font

* @param align

* @param colspan

* @param boderFlag

* @return

*/

public static PdfPCell createCell(String value, com.lowagie.text.Font font, int align,

int colspan, boolean boderFlag) {

PdfPCell cell = new PdfPCell();

cell.setVerticalAlignment(Element.ALIGN_MIDDLE);

cell.setHorizontalAlignment(align);

cell.setColspan(colspan);

cell.setPhrase(new Phrase(value, font));

cell.setPadding(3.0f);

if (!boderFlag) {

cell.setBorder(0);

cell.setPaddingTop(15.0f);

cell.setPaddingBottom(8.0f);

}

return cell;

}


/**

* 创建单元格,设置列数

*

* @param colNumber

* @return

*/

public static PdfPTable createTable(int colNumber) {

PdfPTable table = new PdfPTable(colNumber);

try {

// table.setTotalWidth(maxWidth);

// table.setLockedWidth(true);

table.setHorizontalAlignment(Element.ALIGN_CENTER);

table.getDefaultCell().setBorder(1);

} catch (Exception e) {

e.printStackTrace();

}

return table;

}


/**

* 创建设置不同宽度列的表格

*

* @param widths

* @return

*/

public static PdfPTable createTable(float[] widths) {

PdfPTable table = new PdfPTable(widths);

try {

// table.setTotalWidth(maxWidth);

// table.setLockedWidth(true);

table.setHorizontalAlignment(Element.ALIGN_CENTER);

table.getDefaultCell().setBorder(1);

} catch (Exception e) {

e.printStackTrace();

}

return table;

}


/**

* 创建有下划线的表格

*

* @return

*/

public static PdfPTable createBlankTable() {

PdfPTable table = new PdfPTable(1);

table.getDefaultCell().setBorder(0);

table.addCell(createCell("", keyfont));

table.setSpacingAfter(20.0f);

table.setSpacingBefore(20.0f);

return table;

}


/**

*

* 生成PDF文件,并导出

* @param orderInfo

* @param pageList

* @param pageList2

* @param fileName

* @param response

* @throws Exception

*/

public static void generatePDF(String title, String[] headers, OrderInfo orderInfo,

List<PageObject> pageList, List<PageObject> pageList2,

String fileName, Document document, HttpServletResponse response)

throws Exception {

// 直接往response的输出流中写pdf

OutputStream outputStream = response.getOutputStream();

// 下载格式设置

response.setContentType("APPLICATION/OCTET-STREAM");

response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".pdf");

// documentoutputstream关联

PdfWriter.getInstance(document, outputStream);


// 设置页面大小、还可以设置上下左右边距

document.setPageSize(PageSize.A4);


//生成PDF页眉

HeaderFooter footer = new HeaderFooter(new Phrase(), true);

footer.setBorder(0);//设置边框

footer.setAlignment(Element.ALIGN_CENTER);//对齐设置

document.setFooter(footer);


document.open();


Double totalSum = 0D;

if (orderInfo.getUseType() == 1) {

title = "院内" + title;

} else {

title = "远程" + title;

}

// 表头设置,创建小节标题,往小节中写文本内容

Paragraph par1 = new Paragraph(title, headfont);

par1.setSpacingBefore(10);//之前间隔多少

par1.setSpacingAfter(10);//之后间隔多少

par1.setAlignment(Element.ALIGN_CENTER);

document.add(par1);


// 表头设置,创建小节标题,往小节中写文本内容

Paragraph paragraph = new Paragraph("项目名称: ", keyfont);

paragraph.setSpacingBefore(10);//之前间隔多少

paragraph.setSpacingAfter(10);//之后间隔多少

paragraph.setIndentationLeft(100);//左边缩进设置

Chunk chunk = new Chunk(orderInfo.getoName() + " ");

Chunk chunks1 = new Chunk(" " + "备注: ");

Chunk chunks11 = new Chunk(orderInfo.getDescription() + " ");

paragraph.add(chunk);

paragraph.add(chunks1);

paragraph.add(chunks11);

document.add(paragraph);


DecimalFormat df = new DecimalFormat("#.00");

float[] widths = { 0.03f, 0.03f, 0.12f, 0.05f };

if (pageList.size() > 0) {

// PdfPTable table = createTable(4);

PdfPTable table = new PdfPTable(widths);

table.addCell(createCell("xxxx采集终端", keyfont, Element.ALIGN_CENTER, 4, false));


table.addCell(createCell("序号", keyfont, Element.ALIGN_CENTER));

table.addCell(createCell("数量", keyfont, Element.ALIGN_CENTER));

table.addCell(createCell("描述", keyfont, Element.ALIGN_CENTER));

table.addCell(createCell("单价", keyfont, Element.ALIGN_CENTER));


for (int i = 0; i < headers.length; i++) {

table.addCell(createCell(headers[i], keyfont, Element.ALIGN_CENTER));

}


for (int i = 0; i < pageList.size(); i++) {


PageObject pageObject = pageList.get(i);

table.addCell(createCell((i + 1) + "", textfont));

table.addCell(createCell(pageObject.getAmout() + "", textfont));

table.addCell(createCell(pageObject.getDesc(), textfont));

table.addCell(createCell("" + df.format(pageObject.getPrice()), textfont));

totalSum = totalSum + (pageObject.getAmout() * (pageObject.getPrice()));


}

document.add(table);

}


if (pageList2.size() > 0) {

// PdfPTable table2 = createTable(4);

PdfPTable table2 = new PdfPTable(widths);

table2.addCell(createCell("已选择以下配套设施", keyfont, Element.ALIGN_CENTER, 4, false));


table2.addCell(createCell("序号", keyfont, Element.ALIGN_CENTER));

table2.addCell(createCell("数量", keyfont, Element.ALIGN_CENTER));

table2.addCell(createCell("描述", keyfont, Element.ALIGN_CENTER));

table2.addCell(createCell("单价", keyfont, Element.ALIGN_CENTER));


for (int i = 0; i < headers.length; i++) {

table2.addCell(createCell(headers[i], keyfont, Element.ALIGN_CENTER));

}


for (int i = 0; i < pageList2.size(); i++) {


PageObject pageObject = pageList2.get(i);

table2.addCell(createCell((i + 1) + "", textfont));

table2.addCell(createCell(pageObject.getAmout() + "", textfont));

table2.addCell(createCell(pageObject.getDesc(), textfont));

table2.addCell(createCell("" + df.format(pageObject.getPrice()), textfont));

totalSum = totalSum + (pageObject.getAmout() * (pageObject.getPrice()));


}

document.add(table2);

}


Paragraph paragraph3 = new Paragraph("合计:", keyfont);

paragraph3.setSpacingBefore(10);//之前间隔多少

paragraph3.setSpacingAfter(10);//之后间隔多少

paragraph3.setIndentationLeft(100);//左边缩进设置

Chunk chunk33 = new Chunk("" + df.format(totalSum), textfont);

paragraph3.add(chunk33);

document.add(paragraph3);


document.close();


outputStream.close();


}


}


  1. 页面数据封装对象

package com.wxh.utils;


import java.io.Serializable;



public class PageObject implements Serializable {


/** */

private static final long serialVersionUID = 2844728426887277045L;

private String name; //项目名称

private String meno; //备注

private Long amout; //数量

private String desc; //描述

private Double price; //单价

private Double totalPrice; //合计


/**

*

*/

public PageObject() {

// TODO Auto-generated constructor stub

}


/**

* @param name

* @param meno

* @param amout

* @param desc

* @param price

* @param totalPrice

*/

public PageObject(String name, String meno, Long amout, String desc, Double price,

Double totalPrice) {

super();

this.name = name;

this.meno = meno;

this.amout = amout;

this.desc = desc;

this.price = price;

this.totalPrice = totalPrice;

}


/**

* Getter method for property <tt>name</tt>.

*

* @return property value of name

*/

public String getName() {

return name;

}


/**

* Setter method for property <tt>name</tt>.

*

* @param name value to be assigned to property name

*/

public void setName(String name) {

this.name = name;

}


/**

* Getter method for property <tt>meno</tt>.

*

* @return property value of meno

*/

public String getMeno() {

return meno;

}


/**

* Setter method for property <tt>meno</tt>.

*

* @param meno value to be assigned to property meno

*/

public void setMeno(String meno) {

this.meno = meno;

}


/**

* Getter method for property <tt>amout</tt>.

*

* @return property value of amout

*/

public Long getAmout() {

return amout;

}


/**

* Setter method for property <tt>amout</tt>.

*

* @param amout value to be assigned to property amout

*/

public void setAmout(Long amout) {

this.amout = amout;

}


/**

* Getter method for property <tt>desc</tt>.

*

* @return property value of desc

*/

public String getDesc() {

return desc;

}


/**

* Setter method for property <tt>desc</tt>.

*

* @param desc value to be assigned to property desc

*/

public void setDesc(String desc) {

this.desc = desc;

}


/**

* Getter method for property <tt>price</tt>.

*

* @return property value of price

*/

public Double getPrice() {

return price;

}


/**

* Setter method for property <tt>price</tt>.

*

* @param price value to be assigned to property price

*/

public void setPrice(Double price) {

this.price = price;

}


/**

* Getter method for property <tt>totalPrice</tt>.

*

* @return property value of totalPrice

*/

public Double getTotalPrice() {

return totalPrice;

}


/**

* Setter method for property <tt>totalPrice</tt>.

*

* @param totalPrice value to be assigned to property totalPrice

*/

public void setTotalPrice(Double totalPrice) {

this.totalPrice = totalPrice;

}


}


  1. 业务中调用导出PDF工具类

  1. 比如生成订单,将订单信息导出为PDF,业务涉及的类,以get方式请求导出PDF

OrderController代码:

package com.wxh.controller;



@Controller

@RequestMapping("order")

public class OrderController {


@Autowired

OrderService orderService;


@Autowired

ProductService productService;


 


/**

* 导出PDF

*

* @param request

* @param orderId

* @return

* @throws Exception

*/

@SuppressWarnings("unchecked")

@RequestMapping("pdf")

public void pdf(HttpServletRequest request, HttpServletResponse response, Long orderId)

throws Exception {

PageObject pageObject = null;

List<PageObject> pageList = new ArrayList<PageObject>();

List<PageObject> pageList2 = new ArrayList<PageObject>();


List<PdAmbitionBox> boxs = new ArrayList<PdAmbitionBox>();

List<PdProduct> prods = new ArrayList<PdProduct>();


List<SqlConstantInfo> prodTypes = StringUtils.getSqlConstantInfo(5L);


LogonInfo logonInfo = (LogonInfo) request.getSession().getAttribute("user");

OrderInfo orderInfo = orderService.getOrderInfoById(orderId);

//1.组装数据

if (orderInfo != null

&& (logonInfo.getuId().equals(orderInfo.getuId()) || logonInfo.getUserType().equals(

LogonInfo.USERTYPE_ADMIN))) {


boxs = (List<PdAmbitionBox>) productService.getBoxs();

prods = (List<PdProduct>) productService.getProducts();


List<RelationOrderBox> orderBoxs = orderService.getBoxsByOrderId(orderId);

setBoxValue(orderBoxs, boxs);


List<RelationOrderProd> orderProds = orderService.getProductsByOrderId(orderId);

setProdValue(orderProds, prods);


for (int i = 0; i < orderBoxs.size(); i++) {

PdAmbitionBox box = boxs.get(i);

RelationOrderBox rob = orderBoxs.get(i);

pageObject = new PageObject();

pageObject.setName(orderInfo.getoName());

pageObject.setMeno(orderInfo.getDescription());

pageObject.setAmout(rob.getPdNum());

pageObject.setDesc(box.getBoxName() + "," + box.getCpu() + "," + box.getMemory()

+ "," + box.getHarddisk() + "," + box.getTotalPrice());

pageObject.setPrice(box.getTotalPrice());

pageList.add(pageObject);

}


for (int i = 0; i < orderProds.size(); i++) {

PdProduct product = prods.get(i);

RelationOrderProd rop = orderProds.get(i);

pageObject = new PageObject();

String proName = product.getProductName();

if (proName.contains("-")) {

String[] proNames = proName.split("-");

proName = proNames[0];

}

pageObject.setName(proName);

pageObject.setMeno(product.getProductName());

pageObject.setAmout(rop.getPdNum());

pageObject.setDesc(product.getProductName() + "," + product.getDescription() + ","

+ product.getTotalPrice());

pageObject.setPrice(product.getTotalPrice());

pageList2.add(pageObject);

}


}


//2.生成PDF文件并导出

Document document = new Document(PageSize.A4, 50, 50, 50, 50);


orderService.createPDF(orderInfo, pageList, prods, prodTypes, Calendar.getInstance()

.getTimeInMillis() + "", document, response);

}


}


OrderServiceImpl代码:

package com.wxh.service.impl;


@Service

public class OrderServiceImpl implements OrderService, ServletContextAware {


@Autowired

PdAmbitionBoxDao boxDao;

@Autowired

PdProductDao productDao;

@Autowired

OrderInfoDao orderInfoDao;

@Autowired

RelationOrderBoxDao relationOrderBoxDao;

@Autowired

RelationOrderProdDao relationOrderProdDao;


 

/**

* @param orderInfo

* @param pageList

* @param prods

* @param prodTypes

* @param string

* @param document

* @param response

*/

@Override

public void createPDF(OrderInfo orderInfo, List<PageObject> pageList, List<PdProduct> prods,

List<SqlConstantInfo> prodTypes, String fileName, Document document,

HttpServletResponse response) throws Exception {

//获取模板路径

String filePath = servletContext.getRealPath("/") + "html2pdf/template.html";

String templateContent = " ";

//读取模板文件

FileInputStream fileinputstream = new FileInputStream(filePath);

int lenght = fileinputstream.available();

byte bytes[] = new byte[lenght];

fileinputstream.read(bytes);

fileinputstream.close();


/* 盒子拼接行的展示*/

StringBuilder boxStr = new StringBuilder();

DecimalFormat df = new DecimalFormat("#.00");

Double boxPrice = 0D;

if (pageList.size() > 0) {

for (int i = 0; i < pageList.size(); i++) {

PageObject pageBox = pageList.get(i);

boxStr.append("<tr>");

boxStr.append("<td>" + pageBox.getDesc() + "</td>");

boxStr.append("<td>" + pageBox.getAmout() + "</td>");

boxStr.append("<td>" + "" + df.format(pageBox.getPrice()) + "</td>");

boxStr.append("<td>" + "" + df.format(pageBox.getPrice()) + "</td>");

boxStr.append("</tr>");

boxPrice = boxPrice + pageBox.getAmout() * pageBox.getPrice();

}

}

/* 产品拼接行的展示*/

StringBuilder productStr = new StringBuilder();

Double productPrice = 0D;

PageObject pageObject = null;

List<PageObject> productList = new ArrayList<PageObject>();

List<PageObject> list = new ArrayList<PageObject>();

//map<类型,产品list>

Map<Long, Object> map = new HashMap<Long, Object>();

/*

* 将产品分类,比如服务器有两条记录

* 服务器--低配。。。。

* 服务器--高配。。。。

*/

for (PdProduct product : prods) {

if (product.getIsUse() == 1

&& (orderInfo.getUseType() == product.getUseType() || product.getUseType() == 3)) {

if (product.getRelationOrderProd() != null) {

List list2 = (List) map.get(product.getProductType());

if (list2 == null) {

list2 = new ArrayList();

}

list2.add(product);

map.put(product.getProductType(), list2);

}


}


}


/*

* 生成html模版样式

*/

for (SqlConstantInfo prodType : prodTypes) {

List prodlist = (List) map.get(Long.valueOf(prodType.getCsValue()));

if (prodlist != null && prodlist.size() > 0) {


productStr.append("<div>");

productStr.append("<p>&nbsp;</p>");

productStr.append("<p class=‘tabtitle‘>" + prodType.getCsName() + "</p>");

productStr.append("<div>");

productStr.append("<table border=‘0‘>");


productStr.append("<tr class=‘colTitle‘>");

productStr.append("<td width=‘435‘>名称</td>");

productStr.append("<td width=‘70‘>数量</td>");

productStr.append("<td width=‘105‘>单价</td>");

productStr.append("<td width=‘342‘>金额</td>");

productStr.append("</tr>");


Double itemPrice = 0D;

for (int j = 0; j < prodlist.size(); j++) {

PdProduct prod = (PdProduct) prodlist.get(j);

if (prod.getRelationOrderProd() != null) {

productStr.append("<tr>");

productStr.append("<td>" + prod.getProductName() + "</td>");

productStr

.append("<td>" + prod.getRelationOrderProd().getPdNum() + "</td>");

productStr.append("<td>" + "" + df.format(prod.getTotalPrice()) + "</td>");

productStr.append("<td>" + "" + df.format(prod.getTotalPrice()) + "</td>");

productStr.append("</tr>");


itemPrice += prod.getRelationOrderProd().getPdNum() * prod.getTotalPrice();


productPrice += prod.getRelationOrderProd().getPdNum()

* prod.getTotalPrice();

}


}


productStr.append("</table>");

productStr.append("</div>");

productStr.append("<div class=‘line‘></div>");

productStr.append("<div style=‘float:right;margin-top:10px;‘>总价:¥"

+ df.format(itemPrice) + "</div>");

productStr.append("</div>");

//跳出循环清空

itemPrice = 0D;

}


}


templateContent = new String(bytes, "utf-8");

String useType = "";

if (orderInfo.getUseType() == 1L) {

useType = "院内系统报价单";

} else {

useType = "远程系统报价单";

}

templateContent = templateContent.replaceAll("###useType###", useType);

templateContent = templateContent.replaceAll("###oName###", orderInfo.getoName());

templateContent = templateContent.replaceAll("###gmtModified###",

DateUtils.changeDateToStr(orderInfo.getGmtModified()));

templateContent = templateContent.replaceAll("###orderId###", orderInfo.getOrderId() + "");

//获取图片路径

String fileUrl = PDFUtil.class.getResource("").getPath().replaceAll("%20", " ");

String path = fileUrl.substring(0, fileUrl.indexOf("WEB-INF"))

+ "WEB-INF/config/font/titlogo.jpg";

//jar包中的class文件调用这个接口时返回的path"file:"开头,这里需调用外部的资源文件,所以需要删除file:

if (path.startsWith("file")) {

path = path.substring(5);

}

templateContent = templateContent.replaceAll("###imgsrc###", path);

templateContent = templateContent.replaceAll("###trBox###", boxStr.toString());

templateContent = templateContent.replaceAll("###boxPrice###", df.format(boxPrice));

templateContent = templateContent.replaceAll("###divProduct###", productStr.toString());

templateContent = templateContent.replaceAll("###projectPrice###",

df.format((boxPrice + productPrice)));

templateContent = templateContent.replaceAll("###description###",

orderInfo.getDescription());


// System.out.println("--" + templateContent);


// 直接往response的输出流中写pdf

OutputStream outputStream = response.getOutputStream();

// 下载格式设置

response.setContentType("APPLICATION/OCTET-STREAM");

response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".pdf");


ITextRenderer renderer = new ITextRenderer();

renderer.setDocumentFromString(templateContent);

// 解决中文支持

ITextFontResolver fontResolver = renderer.getFontResolver();

fontResolver.addFont("C:/windows/fonts/simsun.ttc", BaseFont.IDENTITY_H,

BaseFont.NOT_EMBEDDED);


renderer.layout();

renderer.createPDF(outputStream);


outputStream.close();


System.out.println("create pdf done!!");


}


private ServletContext servletContext;


public void setServletContext(ServletContext sc) {

this.servletContext = sc;

//System.out.println("项目的绝对路径为:"+servletContext.getRealPath("/"));

}

}


  1. 总结

自此,整个JavaHTML导出PDF开发过程,大功告成。开发过程中,需要注意的是字体、分页、输出流。

Java将HTML导出为PDF

标签:文本   输出   exception   记录   shm   header   编码   info   eth   

原文地址:http://www.cnblogs.com/huaxinwu/p/7712259.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!