• Java将HTML导出为PDF


     


    大纲内容:

    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;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开发过程,大功告成。开发过程中,需要注意的是字体、分页、输出流。

  • 相关阅读:
    微信小程序用vant,dialog弹出框
    小程序太阳码 ,不发布也可以测试
    php ,通过password与salt共同来验证登录
    vscode 使用less开发微信小程序
    php命名规范
    61键 如何打波浪线
    php 循环使用
    记一次,物业费时间交集问题
    Mac拖拽文件
    python 支持中文
  • 原文地址:https://www.cnblogs.com/huaxinwu/p/7712259.html
Copyright © 2020-2023  润新知