大纲内容:
配置对应jar
编写HTML模板
编写导出PDF工具类
业务中调用PDF工具类
背景
市场上Java导出word、execl较多,比如POI等。反而Java导出PDF实现开源的少之又少。为了防止用户修改自己公司定制的一些文件,因此将一些数据导出PDF,以便用户阅读。对于Java导出PDF,市场上主要有:1.iText实现HTML2PDF,速度快、纠错能力差、支持中文、只支持Unicode编码,一种中文格式,样式单一,开源。2.Flying Ssauser实现HTML2PDF,纠错能力差、支持多种中文字体,部分样式不支持(css3中的部分样式不支持),开源。3.速度快,纠错能力强,支持多种中文字体,商业不开源。
结合市场上的Java将HTML导出PDF开源,都不符合自己需求。因此,自己综合市场的技术,自己采用Flying Ssauser实现导出PDF定制开发。
配置maven依赖
现在JavaEE开发都是采用maven项目,方便jar管理和维护。开发Java将HTML导出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>
编写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> ###description###</p>
</div>
</div>
</body>
</html>
首先,动态变更的数据用字符串变量取代,在Java后台进行替换。其次,对于PDF的分页,在HTML模板中,采用css3的@page进行分页操作。再次,HTML模板中的字体采用window字体库中英文的宋体字体。
编写导出PDF工具类
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");
// 将document与outputstream关联
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();
}
}
页面数据封装对象
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;
}
}
业务中调用导出PDF工具类
比如生成订单,将订单信息导出为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> </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("/"));
}
}
总结
自此,整个Java将HTML导出PDF开发过程,大功告成。开发过程中,需要注意的是字体、分页、输出流。
原文:http://www.cnblogs.com/huaxinwu/p/7712259.html