JAVA中通过HTML+CSS生成指定格式的PDF


import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import com.itextpdf.text.Document;
import com.itextpdf.text.Font;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.strato.base.env.v1_0_0.GlobalEnvironment;
import com.strato.service.assess.api.v1_0_0.paper.Tab;
import com.strato.service.assess.api.v1_0_0.paper.TabQuestion;
import com.strato.service.assess.api.v1_0_0.paper.TabTopic;

public class PDFUtil {
	
	public static String getHtmlStr(String merchantName,Tab assessDefinePaper,String qrcodePath) {
		StringBuffer sb =  new StringBuffer();
        
        sb.append("<!DOCTYPE html>");
        sb.append("<html>");
        sb.append("	<head>");
        sb.append("	<meta charset='utf-8'/>");
        sb.append("	<meta name='keywords' content='' />");
		sb.append("	<meta name='description' content='' />");
        sb.append("	<meta name='viewport' content='width=device-width,initial-scale=1.0'/>");
        sb.append("	<title>"+assessDefinePaper.getLabelName()+"</title>");
        sb.append("	</head>");
        sb.append("	<body>");
        
        sb.append("	<div style='text-align: center;height:auto; margin: 0; width: initial; page-break-after: always; margin: 0 auto; background: #fff; box-sizing: border-box; padding: 15pt;'>");
		sb.append("	    <h1 style='text-align: center; font-size:36pt;padding-top: 60pt; padding-bottom: 15pt;'>"+merchantName+"</h1>");
		sb.append("	    <div style='text-align: center;font-size:20pt;padding-bottom: 30pt;'>"+assessDefinePaper.getLabelName()+"</div>");
		sb.append("	    <div style='text-align: center;padding-bottom: 15pt;'>");
		sb.append("	        <img style='width: 140pt; height:140pt; margin-bottom: 15pt;' alt='二维码' src='"+qrcodePath+"'/>");
		sb.append("	        <p style='line-height: 150%; font-size:14pt;'>希普APP扫码录结果<br/>微信扫码查报告</p>");
		sb.append("	    </div>");

		sb.append("	    <div style='text-align: center;width: 380pt; margin: 70pt auto 0;font-size:14pt;'>");
		sb.append("			<div style='display: block;overflow: hidden; line-height:40pt; height:40pt;'>");
		sb.append("	            <label style='display: block; text-align:left; width: 75pt;float: left;'>儿童姓名:</label>");
		sb.append("				<u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</u>");
		sb.append("	         </div>");
		sb.append("			<div style='display: block;overflow: hidden; line-height:40pt; height:40pt;'>");
		sb.append("	            <label style='display: block; text-align:left; width: 75pt;float: left;'>&nbsp;&nbsp;年龄:</label>");
		sb.append("				<u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</u>");
		sb.append("	         </div>");
		sb.append("			<div style='display: block;overflow: hidden; line-height:40pt; height:40pt;'>");
		sb.append("	            <label style='display: block; text-align:left; width: 75pt;float: left;'>&nbsp;&nbsp;性别:</label>");
		sb.append("				<u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</u>");
		sb.append("	         </div>");
		sb.append("			<div style='display: block;overflow: hidden; line-height:40pt; height:40pt;'>");
		sb.append("	            <label style='display: block; text-align:left; width: 75pt;float: left;'>&nbsp;评估师:</label>");
		sb.append("				<u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</u>");
		sb.append("	         </div>");
		sb.append("			<div style='display: block;overflow: hidden; line-height:40pt; height:40pt;'>");
		sb.append("	            <label style='display: block; text-align:left; width: 75pt;float: left;'>评估日期:</label>");
		sb.append("				<u>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</u>");
		sb.append("	         </div>");
		sb.append("	     </div>");
		sb.append("	  </div>");
        
		
		List<Integer> splitIds = new ArrayList<>();
		
		int pageSize = 27;//一页题数
		List<TabQuestion> tabQuestionList = assessDefinePaper.getTabQuestionList();
		if(tabQuestionList!=null && tabQuestionList.size()>0) {
			for(TabQuestion question : tabQuestionList) {
				if(Integer.valueOf(question.getRowSort())%pageSize==1) {
					splitIds.add(Integer.valueOf(question.getRowSort()));
				}
			}
			//1页开始
			sb.append("	<div style='page-break-after: always;background: #fff; box-sizing: border-box; padding: 15pt;'>");
			sb.append("	    <table cellpadding='0' cellspacing='0' style='border-collapse: collapse; width: 100%; table-layout: fixed; font-size:10pt'>");
			sb.append("	        <thead>");
			sb.append("	           <tr>");
			sb.append("	               <td align='center' style='border:solid 1px #000; background: #eee; height:26pt; line-height: 26pt; padding: 0 10pt;' width='8%'>序号</td>");
			sb.append("	               <td align='center' style='border:solid 1px #000; background: #eee; height:26pt; line-height: 26pt; padding: 0 10pt;' width='65%'>评估项</td>");
			sb.append("				   <td align='center' style='border:solid 1px #000; background: #eee; height:26pt; line-height: 26pt; padding: 0 10pt;' width='5%' rowspan='"+pageSize+1+"'>");
			sb.append("	    	<div style=' width: 1px; height:80pt; border-left:dashed 1px #aaa; margin: 30pt auto;'></div>");
			sb.append("	        <div style='font-size:9pt; color:#aaa; text-align: center; line-height: 15pt;'>→<br/>扫<br/>描<br/>区<br/>→</div>");
			sb.append("	        <div style=' width: 1px; height:80pt; border-left:dashed 1px #aaa; margin: 30pt auto;'></div>");
			sb.append("	        <div style='font-size:9pt; color:#aaa; text-align: center; line-height: 15pt;'>←<br/>显<br/>示<br/>区<br/>←</div>");
			sb.append("	        <div style=' width: 1px; height:80pt; border-left:dashed 1px #aaa; margin: 30pt auto;'></div>");
			sb.append("		</td>");
			sb.append("	               <td align='center' style='border:solid 1px #000; background: #eee; height:26pt; line-height: 26pt; padding: 0 10pt;' width='10%'>评分</td>");
			sb.append("	               <td align='center' style='border:solid 1px #000; background: #eee; height:26pt; line-height: 26pt; padding: 0 10pt;' width='13%'></td>");
			sb.append("	           </tr>");
			sb.append("	       </thead>");
			sb.append("	        <tbody>");
			
				for(TabQuestion question : tabQuestionList) {
					int index =0;
					for(int splitId : splitIds) {
						if(Integer.valueOf(question.getRowSort())==splitId && splitId!=1) {//2n页开始
							sb.append("	        </tbody>");
							sb.append("	    </table>");
							sb.append("	</div>");
							
							sb.append("	<div style='page-break-after: always;background: #fff; box-sizing: border-box; padding: 15pt;'>");
							sb.append("	    <table cellpadding='0' cellspacing='0' style='border-collapse: collapse; width: 100%; table-layout: fixed; font-size:10pt'>");
							sb.append("	        <thead>");
							sb.append("	           <tr>");
							sb.append("	               <td align='center' style='border:solid 1px #000; background: #eee; height:26pt; line-height: 26pt; padding: 0 10pt;' width='8%'>序号</td>");
							sb.append("	               <td align='center' style='border:solid 1px #000; background: #eee; height:26pt; line-height: 26pt; padding: 0 10pt;' width='65%'>评估项</td>");
							sb.append("				   <td align='center' style='border:solid 1px #000; background: #eee; height:26pt; line-height: 26pt; padding: 0 10pt;' width='5%' rowspan='"+pageSize+1+"'>");
							sb.append("	    	<div style=' width: 1px; height:80pt; border-left:dashed 1px #aaa; margin: 30pt auto;'></div>");
							sb.append("	        <div style='font-size:9pt; color:#aaa; text-align: center; line-height: 15pt;'>→<br/>扫<br/>描<br/>区<br/>→</div>");
							sb.append("	        <div style=' width: 1px; height:80pt; border-left:dashed 1px #aaa; margin: 30pt auto;'></div>");
							sb.append("	        <div style='font-size:9pt; color:#aaa; text-align: center; line-height: 15pt;'>←<br/>显<br/>示<br/>区<br/>←</div>");
							sb.append("	        <div style=' width: 1px; height:80pt; border-left:dashed 1px #aaa; margin: 30pt auto;'></div>");
							sb.append("		</td>");
							sb.append("	               <td align='center' style='border:solid 1px #000; background: #eee; height:26pt; line-height: 26pt; padding: 0 10pt;' width='10%'>评分</td>");
							sb.append("	               <td align='center' style='border:solid 1px #000; background: #eee; height:26pt; line-height: 26pt; padding: 0 10pt;' width='13%'></td>");
							sb.append("	           </tr>");
							sb.append("	       </thead>");
							sb.append("	        <tbody>");
							sb.append("	<tr>");
							sb.append("		<td align='center' style=' border:solid 1px #000; height:26pt; line-height: 26pt;padding: 0pt 10pt;'>"+question.getRowSort()+"</td>");
							String optionStr = "[";
							List<TabTopic> tabTopicList = question.getTabQuestionScore().getTabTopicList();
							List<String> optionNames = tabTopicList.stream().map(e -> e.getOptionName()).collect(Collectors.toList());
							optionStr+= optionNames.stream().collect(Collectors.joining("/"))+"]";
							
							sb.append("		<td align='left'  style='font-size:8pt; border:solid 1px #000; height:26pt; line-height: 26pt;padding: 0pt 10pt;'>"+optionStr+question.getTabQuestionDetail()+"</td>");
							sb.append("		<td style=' border:solid 1px #000; height:26pt; line-height: 26pt;padding: 0pt 10pt;'></td>");
							sb.append("		<td align='center' style=' border:solid 1px #000; height:26pt; line-height: 26pt;padding: 0pt 10pt;background:#f5f5f5;'>"+AssessCheckCode.getCode(Integer.valueOf(question.getRowSort()), question.getTabQuestionDetail())+"</td>");
							sb.append("	</tr>");
							index = splitId;
							break;
						}
				}
				if(Integer.valueOf(question.getRowSort())!=index) {
					sb.append("	<tr>");
					sb.append("		<td align='center' style=' border:solid 1px #000; height:26pt; line-height: 26pt;padding: 0pt 10pt;'>"+question.getRowSort()+"</td>");
					String optionStr = "[";
					List<TabTopic> tabTopicList = question.getTabQuestionScore().getTabTopicList();
					List<String> optionNames = tabTopicList.stream().map(e -> e.getOptionName()).collect(Collectors.toList());
					optionStr+= optionNames.stream().collect(Collectors.joining("/"))+"]";
					sb.append("		<td align='left'  style='font-size:8pt; border:solid 1px #000; height:26pt; line-height: 26pt;padding: 0pt 10pt;'>"+optionStr+question.getTabQuestionDetail()+"</td>");
					sb.append("		<td style=' border:solid 1px #000; height:26pt; line-height: 26pt;padding: 0pt 10pt;'></td>");
					sb.append("		<td align='center' style=' border:solid 1px #000; height:26pt; line-height: 26pt;padding: 0pt 10pt;background:#f5f5f5;'>"+AssessCheckCode.getCode(Integer.valueOf(question.getRowSort()), question.getTabQuestionDetail())+"</td>");
					sb.append("	</tr>");
				}
				
				if(Integer.valueOf(question.getRowSort())==tabQuestionList.size()) {//最后一个
					if(Integer.valueOf(question.getRowSort())%pageSize!=1) {
						sb.append("	        </tbody>");
						sb.append("	    </table>");
						sb.append("	</div>");
					}
				}
			}
		}
        sb.append("</body>");
        sb.append("</html>");
        
        return sb.toString();
	}
	
	public static void pdfProcess(String htmlString, String pdfFilePath) throws Exception {
		
		XMLWorkerFontProvider fontProvider = new XMLWorkerFontProvider(){
	        @Override
	        public Font getFont(String fontname, String encoding, float size, int style) {
	            return super.getFont(fontname == null ? "宋体" : fontname, encoding, size, style);
	        }
	    };
		
        Document document = new Document(PageSize.A4);
        PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(pdfFilePath));
        document.open();
        document.addCreationDate();
        XMLWorkerHelper helper = XMLWorkerHelper.getInstance();
        InputStream inputStream = null;
        helper.parseXHtml(pdfWriter, document, new ByteArrayInputStream(htmlString.getBytes("utf-8")), inputStream, Charset.forName("UTF-8"),fontProvider);
        document.close();
    }
	
	public static String generatePaperTemplateByHtml(String merchantName,String pdfname, Tab assessDefinePaper,String qrcodePath) throws Exception {
		String pdfDir=GlobalEnvironment.getInstance().resolveString("${strato.file.local.rootDir}");
		File dir=new File(pdfDir);
		String pdfUrl =pdfDir+"/"+pdfname;
		String htmlStr = getHtmlStr(merchantName,assessDefinePaper,qrcodePath);
		pdfProcess(htmlStr, pdfUrl);
		return pdfUrl;
	}
	
	public static void main(String[] args) {
		int size = 139;
		for(int i=1;i<=size;i++) {
			System.out.println(i+":"+(i%31==0));
		}
		
	}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值