加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java之生成条形码、PDF、HTML FreeMarker之根据模型

发布时间:2020-12-15 07:15:15 所属栏目:Java 来源:网络整理
导读:关于Java生成HTML,可参考我的这篇文章:FreeMarker之根据模型生成HTML代码 当然了,该篇文章也会给你很多启发,比如,根据html生成html,大家不要小看这个,著名的WordPress博客文章,本质上就是这个机制,每发表一篇文章相当于新生成的一个HTML,内容不一样

关于Java生成HTML,可参考我的这篇文章:FreeMarker之根据模型生成HTML代码

当然了,该篇文章也会给你很多启发,比如,根据html生成html,大家不要小看这个,著名的WordPress博客文章,本质上就是这个机制,每发表一篇文章相当于新生成的一个HTML,内容不一样,样式基本是一致的。

下面进入正题:

一、导入Maven依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    modelVersion>4.0.0</groupId>com.foreseeartifactId>mypdfversion>0.0.1-SNAPSHOTdependencies>
        dependency>
            >com.itextpdf>itext-asian>5.2.0>itextpdf>5.4.2>org.xhtmlrenderer>core-renderer>R8>org.freemarker>freemarker>2.3.23>

        >net.sf.barcode4j>barcode4j-light>2.0>

    >
project>

?

二、编写Java代码

package com.beck.util;

import java.awt.image.BufferedImage;
 java.io.ByteArrayOutputStream;
 java.io.File;
 java.io.FileOutputStream;
 java.io.IOException;
 java.io.OutputStream;
 org.krysalis.barcode4j.HumanReadablePlacement;
 org.krysalis.barcode4j.impl.code39.Code39Bean;
 org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
 org.krysalis.barcode4j.tools.UnitConv;
 sun.misc.BASE64Encoder;

public class BarcodeUtil {
    
    static final String IMG_TYPE_PNG="image/png";
    
    final String IMG_TYPE_GIF="image/gif"final String IMG_TYPE_JPEG="image/jpeg"static String generateToBase64(String msg,String imgType) throws IOException {
        ByteArrayOutputStream ous = new ByteArrayOutputStream();
        generateToStream(msg,imgType,ous);
        BASE64Encoder encoder =  BASE64Encoder();
        return encoder.encode(ous.toByteArray());
    }

    static File generateToFile(String msg,String imgType,File file)
             IOException {
        FileOutputStream out =  FileOutputStream(file);
        try {
            generateToStream(msg,out);
        } finally {
            if (out != null) {
                out.close();
            }
        }
         file;
    }

    byte[] generateToByte(String msg,1)"> IOException {
        ByteArrayOutputStream out =  ByteArrayOutputStream();
         out.toByteArray();
        } ) {
                out.close();
            }
        }
    }

    void generateToStream(String msg,OutputStream out)
             IOException {
        if (msg == null || out == ) {
            ;
        }
        Code39Bean bean =  Code39Bean();
        // 精细度
        int dpi = 150;
         module宽度
        double moduleWidth = UnitConv.in2mm(1.0f / dpi);
        bean.setModuleWidth(moduleWidth);
         不显示文字
        bean.setMsgPosition(HumanReadablePlacement.HRP_NONE);
        bean.setHeight(5);
        bean.setWideFactor(3);
        bean.doQuietZone(false);
    
         输出到流
        BitmapCanvasProvider canvas =  BitmapCanvasProvider(out,dpi,BufferedImage.TYPE_BYTE_BINARY,false,0);
         生成条形码
        bean.generateBarcode(canvas,msg);
         结束绘制
        canvas.finish();
    }


}

?

 java.io.OutputStreamWriter;
 java.io.StringWriter;
 java.io.Writer;
 java.util.HashMap;
 java.util.Locale;
 java.util.Map;

 freemarker.template.Configuration;
 freemarker.template.Template;

 FreemarkerTemplate {

    private final Configuration configuration =  Configuration(
            Configuration.VERSION_2_3_23);
    private String charset;

    public FreemarkerTemplate(String charset) {
        this.charset = charset;
        configuration.setEncoding(Locale.CHINA,charset);
        configuration.setClassicCompatible(true);处理空值为空字符串  
    }

     setTemplateClassPath(Class resourceLoaderClass,String basePackagePath) {
        configuration.setClassForTemplateLoading(resourceLoaderClass,basePackagePath);
    }

     setTemplateDirectoryPath(String templatePath)
             IOException {
        configuration.setDirectoryForTemplateLoading( File(templatePath));
    }

     processToStream(String templateFileName,Map<String,Object> dataMap,Writer writer)  Throwable {
        Template template = configuration.getTemplate(templateFileName);
        template.process(dataMap,writer);
    }

     processToFile(String templateFileName,File outFile)  Throwable {
        Writer writer = new OutputStreamWriter( FileOutputStream(outFile),charset);
         {
            processToStream(templateFileName,dataMap,writer);
        } catch (Throwable e) {
            e.printStackTrace();
        } if (writer != ) {
                writer.close();
            }
        }
    }

     String processToString(String templateFileName,Object> dataMap) new StringWriter(2048 writer.toString();
        } ) {
                writer.close();
            }
        }
    }


}

?

 java.io.OutputStream;

 org.xhtmlrenderer.pdf.ITextFontResolver;
 org.xhtmlrenderer.pdf.ITextRenderer;

 com.itextpdf.text.pdf.BaseFont;

 PDFUtils {
    static String fontBasePath=PDFUtils.class.getResource("/").getPath()+"font/";
     htmlFileToPDFStream(File htmlFile,OutputStream output,File imageBaseURL)  Throwable {
        if (htmlFile == throw new RuntimeException("htmlFile is null");
        }
        if (output == new RuntimeException("output is null");
        }

         生成ITextRenderer实例
        ITextRenderer renderer =  ITextRenderer();
         关联html页面
        renderer.setDocument(htmlFile.toURI().toURL().toString());
         设置获取图片的基本路径
        renderer.getSharedContext().setBaseURL(
                imageBaseURL.toURI().toURL().toString());
         设置字体路径,必须和html设置一致
        ITextFontResolver fontResolver = renderer.getFontResolver();
        
        
        fontResolver.addFont(fontBasePath+"msyh.ttc",BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
        fontResolver.addFont(fontBasePath+"msyhl.ttc" htmlFileToPDFFile(File htmlFile,File pdfFile,1)"> Throwable {
        OutputStream output =  FileOutputStream(pdfFile);
         {
            htmlFileToPDFStream(htmlFile,output,imageBaseURL);
        } if (output != ) {
                output.close();
            }
        }
    }

}

?

 Receipt {
     String receiptType;
    double amount;
     String getReceiptType() {
         receiptType;
    }
     setReceiptType(String receiptType) {
        this.receiptType = getAmount() {
         amount;
    }
    void setAmount( amount) {
        this.amount = amount;
    }
}

?

三、在src/main/resources建立HTML页面和相关的文件夹

建立font、images、templates文件夹

文件夹如图所示:

?

html代码:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>报销单</title>
<style type="text/css" rel="stylesheet">
* {
    margin: 0;
    padding: 0;
}
body {
    font-family: "Microsoft YaHei UI";
    font-size: 12px;
    max-width: 555px;
    margin: 0 auto;
    padding: 20px;
}
h1 {
    text-align: center;
    font-size: 18px;
    color: #000weight: bold;
}
.comptitle {
    height: 66px;
}
.comptitle h2 {
    float: left;
    height: 66px;
    line-height: 66px;
    font-size: 14px;
    color: #000weight: bold;
}
.barcode {
    width: 162px;
    : right;
    padding: 10px 0;
    text-align: center;
}
.barcode img {
    width: 162px;
    height: 30px;
    display: table-cell;
    vertical-align: middle;
    margin-bottom: 5px;
}
.barcode h3 {
    font-size: 12px;
    color: #000;
}
.stafftbl,.detailstbl,.approverrd {
    border-collapse: collapse;
    border: 1px solid #f3f3f3;
}
.stafftbl th,.stafftbl td,.detailstbl th,.detailstbl td,.approverrd th,.approverrd td {
    height: 20px;
    line-height: 20px;
    border: 1px solid #f3f3f3;
}
.stafftbl th {
    font-weight: normal;
    background: #f8f9fd;
    text-align: right;
    color: #777;
    padding-right: 12px;
}
.stafftbl td {
    padding-left: 10px;
}
.wrap p {
    color: #000;
    margin: 12px 0 10px;
}
.detailstbl th,.approverrd th {
    font-weight: normal;
    color: #777;
    background: #f8f9fd;
    border: none;
}
.detailstbl td,.approverrd td {
    text-align: center;
}
.sum {
    background: #f8f9fd;
    color: #777;
}
.detailstbl td.sumdata {
    text-align: right;
    padding-right: 20px;
    font-weight: bold;
}
</style>
</head>

<body>
<div class="wrap">
  <h1>费用报销单</h1>
  <div class="comptitle">
    <h2>*****有限公司</h2>
    <div class="barcode"><img src="${barcodeImg}" alt=""></img>
       <h3>${barcode}</h3>
    </div>
  </div>
  <table width="100%" border="0" cellspacing="0" cellpadding="0" class="stafftbl">
    <tbody>
      <tr>
        <th width="18%">报销人</th>
        <td width="32%">${userName}</td>
        <th width="18%">填写日期</th>
        <td>${submitDate}</td>
      </tr>
      <tr>
        <th>费用所属部门</th>
        <td colspan="3">${deptName}</td>
      </tr>
      <tr>
        <th>所属项目</th>
        <td colspan="3">运营平台2.0</td>
      </tr>
      <tr>
        <th>报销事由</th>
        <td colspan="3">${reimReason}</td>
      </tr>
    </tbody>
  </table>
  <p>费用明细</p>
  <table width="100%" border="0" cellspacing="0" cellpadding="0" class="detailstbl">
    <tbody>
      <tr>
       
        <th width="8%">序号</th>
        <th>发票类型</th>
        <th width="10%">发票张数</th>
        <th width="12%">发票金额</th>
        <th width="12%">报销金额</th>
        <th>专票税额</th>
        <th width="28%">用途</th>
      </tr>
      <#list receiptList as item>
      <tr>
        <td >${list_index+1}</td>
        <td>${item.receiptType}</td>
        <td>1</td>
        <td>¥${item.amount}</td>
        <td>¥${item.amount}</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
      </tr>
      </#list>
      <tr>
        <td colspan="2" class="sum">总报销金额(小写)</td>
        <td colspan="5" class="sumdata" >¥259.46</td>
      </tr>
      <tr>
        <td colspan="2" class="sum">总报销金额(大写)</td>
        <td colspan="5" class="sumdata" >贰佰伍拾玖元肆角陆分</td>
      </tr>
    </tbody>
  </table>
  <p>审批记录</p>
  <table width="100%" border="0" cellspacing="0" cellpadding="0" class="approverrd">
    <tbody>
      <tr>
        <th width="8%">序号</th>
        <th>节点名称</th>
        <th>电子签名</th>
        <th>签名日期</th>
        <th width="8%">操作</th>
        <th width="25%">备注</th>
      </tr>
      <tr>
        <td>1</td>
        <td>提交</td>
        <td>张三/平台支撑部</td>
        <td>2018-09-18  16:18:41</td>
        <td>提交</td>
        <td>&nbsp;</td>
      </tr>
    </tbody>
  </table>
</div>
</body>
</html>

?

?图片要求必须符合png、jpg等格式,只要是这些格式的都行。

?

四、编写测试类

 java.util.ArrayList;
 java.util.List;
 java.util.Map;
 java.util.UUID;

 Test {

    void main(String[] args)  Throwable {
         
        String barcode = "12345678910";
        String uuid=UUID.randomUUID().toString();
        String htmlBasePath="E://Demo//workspace//mypdf//src//main//resources//template";html的根目录
        String tempathBasePath=Test.class.getResource("/").getPath()+"template/";模板路径
        String pdfBasePath="E://Demo//workspace//mypdf//src//main//resources//template";生成的pdf目录
        
        String barCodePath="E://Demo//workspace//mypdf//src//main//resources//images//"+uuid+".png";
        String htmlPath=htmlBasePath+uuid+".html";
        String pdfPath=pdfBasePath+uuid+".pdf";
        
        生成条形码
        File barCodeFile= File(barCodePath);
        BarcodeUtil.generateToFile(barcode,BarcodeUtil.IMG_TYPE_PNG,barCodeFile);
        System.out.println("生成条形码完成!"生成html
        FreemarkerTemplate tp=new FreemarkerTemplate("UTF-8");
        tp.setTemplateDirectoryPath(tempathBasePath);
        封装数据 start ,必须是Map
        Map<String,Object> dataMap = new HashMap<String,Object>();
        dataMap.put("barcode");
        dataMap.put("submitDate","2018-09-18");
        dataMap.put("deptName","研发平台"费用明细
        List<Receipt> receiptList=new ArrayList<Receipt>();Receipt 必须是public类型的类
        Receipt r1= Receipt();
        r1.setReceiptType("普通发票");
        r1.setAmount(100);
        
        Receipt r2= Receipt();
        r2.setReceiptType("普通发票");
        r2.setAmount(100);
        
        receiptList.add(r1);
        receiptList.add(r2);
        
        dataMap.put("receiptList"封装数据 end
        File htmlFile= File(htmlPath);
        tp.processToFile("expense.html"生成pdf
        PDFUtils.htmlFileToPDFFile(htmlFile,new File(pdfPath),1)"> File(htmlBasePath));
        System.out.println("生成pdf完成!");
        

    }

}

?

运行结果如图所示(控制台打印这些就表示没有问题,如果控制台报错,常见错误就是文件找不到异常,改下路径就可以了,一般情况是没有其他错误):

?

pdf显示如图:

?

html显示如图:

?

条形码显示如图:

?

源码地址:https://github.com/youcong1996/study_simple_demo.git

如果实在上述代码,不能运行,大家可以将源码移植过来,运行效果是没有问题的。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读