6 changed files with 279 additions and 23 deletions
@ -0,0 +1,101 @@ |
|||||
|
package org.dromara.business.utils; |
||||
|
|
||||
|
import cn.hutool.extra.spring.SpringUtil; |
||||
|
import com.itextpdf.text.Document; |
||||
|
import com.itextpdf.text.DocumentException; |
||||
|
import com.itextpdf.text.Font; |
||||
|
import com.itextpdf.text.pdf.BaseFont; |
||||
|
import com.itextpdf.text.pdf.PdfWriter; |
||||
|
import com.itextpdf.tool.xml.XMLWorkerFontProvider; |
||||
|
import com.itextpdf.tool.xml.XMLWorkerHelper; |
||||
|
import freemarker.template.TemplateException; |
||||
|
import jakarta.servlet.http.HttpServletResponse; |
||||
|
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; |
||||
|
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; |
||||
|
|
||||
|
import java.io.ByteArrayInputStream; |
||||
|
import java.io.ByteArrayOutputStream; |
||||
|
import java.io.IOException; |
||||
|
import java.net.URLEncoder; |
||||
|
import java.nio.charset.Charset; |
||||
|
import java.nio.charset.StandardCharsets; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* Html转换Pdf |
||||
|
* |
||||
|
* @author :Mall |
||||
|
* @date :Created in 2022-04-25 |
||||
|
*/ |
||||
|
public class HtmlConvertPdfHelper { |
||||
|
|
||||
|
/** |
||||
|
* Freemarker的配置类,模板目录默认 在 resources下的 templates |
||||
|
*/ |
||||
|
private static FreeMarkerConfigurer freeMarkerConfigurer = SpringUtil.getBean(FreeMarkerConfigurer.class); |
||||
|
|
||||
|
public static void renderTplFileToPDF(String fileName , String templateName, Map<String, Object> datas, HttpServletResponse response) { |
||||
|
try { |
||||
|
response.setCharacterEncoding(StandardCharsets.UTF_8.name()); // 字符集编码
|
||||
|
response.setContentType("application/pdf;"); |
||||
|
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8")); |
||||
|
response.addHeader("Access-Control-Allow-Origin", "*"); // 实现跨域
|
||||
|
byte[] bytes = htmlConvertPDF(datas, templateName); |
||||
|
// 将生成的文档写入到响应的输出流中
|
||||
|
response.reset(); // 重置响应
|
||||
|
response.getOutputStream().write(bytes); |
||||
|
response.getOutputStream().flush(); |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* freemarker转PDF |
||||
|
* |
||||
|
* @param templateName ftl文件名称,需要在resources/templates目录下 |
||||
|
* @return |
||||
|
* @throws IOException |
||||
|
*/ |
||||
|
public static byte[] htmlConvertPDF(Object map,String templateName) throws IOException, TemplateException, DocumentException { |
||||
|
String htmlText = FreeMarkerTemplateUtils.processTemplateIntoString(freeMarkerConfigurer.getConfiguration().getTemplate(templateName), map); |
||||
|
return htmlConvertPDF(htmlText); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 根据HTML内容转Image |
||||
|
* |
||||
|
* @param htmText HTML文本字符串 |
||||
|
*/ |
||||
|
public static byte[] htmlConvertPDF(String htmText) throws DocumentException, IOException { |
||||
|
//最终返回的byte流
|
||||
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); |
||||
|
//第一步,创建一个 iTextSharp.text.Document对象的实例:
|
||||
|
Document document = new Document(); |
||||
|
//第二步,为该Document创建一个Writer实例:
|
||||
|
PdfWriter writer = PdfWriter.getInstance(document, byteArrayOutputStream); |
||||
|
//第三步,打开当前Document
|
||||
|
document.open(); |
||||
|
XMLWorkerHelper.getInstance().parseXHtml(writer, document, new ByteArrayInputStream(htmText.getBytes()), null, Charset.defaultCharset(), new AsianFontProvider()); |
||||
|
document.close(); |
||||
|
return byteArrayOutputStream.toByteArray(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 用于中文显示的Provider |
||||
|
*/ |
||||
|
class AsianFontProvider extends XMLWorkerFontProvider { |
||||
|
@Override |
||||
|
public Font getFont(final String fontname, String encoding, float size, int style) { |
||||
|
try { |
||||
|
BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); |
||||
|
return new Font(bfChinese, size, style); |
||||
|
} catch (Exception e) { |
||||
|
} |
||||
|
return super.getFont(fontname, encoding, size, style); |
||||
|
} |
||||
|
} |
||||
|
|
@ -0,0 +1,124 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html> |
||||
|
<head> |
||||
|
<title>Early Warning Record</title> |
||||
|
<style> |
||||
|
table, th, td { |
||||
|
border: 1px solid black; |
||||
|
border-collapse: collapse; |
||||
|
text-align: center; |
||||
|
} |
||||
|
h2, p { |
||||
|
text-align: left; |
||||
|
margin-top: 40px; |
||||
|
margin-left: 60px; |
||||
|
} |
||||
|
table { |
||||
|
margin: 40px auto; |
||||
|
width: 100%; |
||||
|
} |
||||
|
h2 { |
||||
|
color: #1b5aa1; |
||||
|
} |
||||
|
td { |
||||
|
word-wrap: break-word; |
||||
|
word-break: break-all; |
||||
|
} |
||||
|
</style> |
||||
|
</head> |
||||
|
<body> |
||||
|
|
||||
|
<h2>一、报表日期</h2> |
||||
|
<p>${startTime?if_exists}~${endTime?if_exists}</p> |
||||
|
<h2>二、数据情况</h2> |
||||
|
<p>预警信息总计:${total?if_exists}条;未处理:${todo?if_exists}条; 已完结:${finish?if_exists}条; 已忽略:${cancel?if_exists}条。</p> |
||||
|
<p>详情如下</p> |
||||
|
|
||||
|
<table> |
||||
|
<!-- 使用 colgroup 和 col 标签为每一列设置不同宽度 --> |
||||
|
<colgroup> |
||||
|
<col style="width: 5%;"/> |
||||
|
<col style="width: 10%;"/> |
||||
|
<col style="width: 10%;"/> |
||||
|
<col style="width: 10%;"/> |
||||
|
<col style="width: 10%;"/> |
||||
|
<col style="width: 10%;"/> |
||||
|
</colgroup> |
||||
|
<tbody> |
||||
|
<tr> |
||||
|
<td>序号</td> |
||||
|
<td>预警名称</td> |
||||
|
<td>所属部门</td> |
||||
|
<td>预警状态</td> |
||||
|
<td>经纬度</td> |
||||
|
<td>预警时间</td> |
||||
|
</tr> |
||||
|
<#if (alertList?size gt 0) && alertList??> |
||||
|
<#list alertList as item> |
||||
|
<tr> |
||||
|
<td>${item_index + 1}</td> |
||||
|
<td>${item.jobName?if_exists}</td> |
||||
|
<td>${item.deptName?if_exists}</td> |
||||
|
<td>${item.handleType?if_exists}</td> |
||||
|
<td>${item.lng?if_exists} ${item.lat?if_exists}</td> |
||||
|
<td>${item.createTime?datetime?string('yyyy-MM-dd HH:mm:ss')}</td> |
||||
|
</tr> |
||||
|
</#list> |
||||
|
</#if> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
|
||||
|
<script> |
||||
|
|
||||
|
</script> |
||||
|
<#if (alertList?size gt 0) && alertList??> |
||||
|
<#list alertList as item> |
||||
|
<h2>(${item_index + 1})预警信息:${item.jobName?if_exists}</h2> |
||||
|
<table> |
||||
|
<colgroup> |
||||
|
<col style="width: 50%;"/> |
||||
|
<col style="width: 50%;"/> |
||||
|
</colgroup> |
||||
|
<tbody> |
||||
|
<tr> |
||||
|
<td style="height: 50px;">前期影像</td> |
||||
|
<td style="height: 50px;">后期影像</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td><img src="${item.maxImages}" alt="前期影像1" style="width: 330px; height: 290px;"/></td> |
||||
|
<td><img src="${item.images}" alt="前期影像2" style="width: 330px; height: 290px;"/></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td><img src="${item.maxMateSourceImgUrl}" alt="后期影像1" style="width: 330px; height: 290px;"/></td> |
||||
|
<td><img src="${item.mateSourceImgUrl}" alt="后期影像2" style="width: 330px; height: 290px;"/></td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
|
||||
|
<#if item.assignUserId??> |
||||
|
<h2>处置内容</h2> |
||||
|
|
||||
|
<table style="border-collapse: collapse; border: none; margin-top: 50px;width: 50%;height: 50%;"> |
||||
|
<tbody> |
||||
|
<tr> |
||||
|
<td style="border: none; text-align: left; height: 30px; vertical-align: top;">识别类型:${item.labelCn?if_exists}</td> |
||||
|
<td style="border: none; text-align: left; height: 30px; vertical-align: top;">指派人员: ${item.assignUserName?if_exists}</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td style="border: none; text-align: left; height: 30px; vertical-align: top;">预警时间: ${item.createTime?datetime?string('yyyy-MM-dd HH:mm:ss')}</td> |
||||
|
<td style="border: none; text-align: left; height: 30px; vertical-align: top;">指派时间: |
||||
|
<#if item.assignDate??> |
||||
|
${item.assignDate?datetime?string('yyyy-MM-dd HH:mm:ss')} |
||||
|
</#if> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td colspan="2" style="border: none; text-align: left; height: 40px;width: 50%; vertical-align: top;" >任务内容: ${item.reason?if_exists}</td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</#if> |
||||
|
</#list> |
||||
|
</#if> |
||||
|
</body> |
||||
|
</html> |
Loading…
Reference in new issue