package com.estate.expert.admin.stat.report.builder;
|
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.deepoove.poi.XWPFTemplate;
|
import com.deepoove.poi.config.Configure;
|
import com.deepoove.poi.config.ConfigureBuilder;
|
import com.deepoove.poi.data.ChartMultiSeriesRenderData;
|
import com.deepoove.poi.data.ChartSingleSeriesRenderData;
|
import com.deepoove.poi.data.Charts;
|
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
|
import com.estate.expert.admin.service.UserFileService;
|
import com.estate.expert.admin.stat.report.render.AbstractInfoTablePolicy;
|
import com.estate.expert.admin.stat.report.render.CheckInfoTablePolicy;
|
import com.estate.expert.admin.stat.report.render.CustomPictureRenderPolicy;
|
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.util.CollectionUtils;
|
|
import java.io.IOException;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
/**
|
* 第三方评估报告构建器
|
*/
|
public class SystemReportBuilder implements ReportBuilderBase {
|
|
private static final String DEFAULT_TEMPLATE_FILE = "第三方评估报告.docx";
|
|
protected UserFileService userFileService;
|
|
private final String templateFile;
|
|
public SystemReportBuilder(UserFileService userFileService) {
|
this(userFileService, DEFAULT_TEMPLATE_FILE);
|
}
|
|
public SystemReportBuilder(UserFileService userFileService, String templateFile) {
|
this.userFileService = userFileService;
|
this.templateFile = templateFile;
|
}
|
|
/**
|
* 构建第三方评估报告
|
* @param data 数据
|
* @param templateConfig 模板配置
|
* @return 第三方评估报告
|
*/
|
@Override
|
public XWPFTemplate buildReport(JSONObject data, Map<String, Integer> templateConfig) {
|
var res = new ClassPathResource("templates/" + templateFile);
|
|
var viewConfig = templateConfig != null ? toViewConfig(templateConfig) : null;
|
var builder = initConfig(viewConfig);
|
var model = initModel(data);
|
|
if(viewConfig != null)
|
model.put("config", viewConfig);
|
|
try {
|
return XWPFTemplate.compile(res.getInputStream(), builder.build()).render(model);
|
} catch (IOException e) {
|
throw new RuntimeException(e);
|
}
|
}
|
|
/**
|
* 转换视图配置
|
* @param templateConfig 模板配置
|
* @return 视图配置
|
*/
|
private Map<String, Boolean> toViewConfig(Map<String, Integer> templateConfig){
|
var map = new HashMap<String, Boolean>();
|
for (var entry : templateConfig.entrySet()) {
|
var value = entry.getValue();
|
for(int i = 0; i < 2; i++){
|
map.put(entry.getKey() + i, value == i);
|
}
|
}
|
return map;
|
}
|
|
/**
|
* 初始化配置
|
* @param viewConfig 视图配置
|
* @return 配置构建器
|
*/
|
private ConfigureBuilder initConfig(Map<String, Boolean> viewConfig){
|
ConfigureBuilder builder = Configure.builder();
|
builder.bind("data.设备信息", new LoopRowTableRenderPolicy());
|
builder.bind("data.设备分组信息", new LoopRowTableRenderPolicy());
|
builder.bind("data.评估结果.隐患等级分布.分项", new LoopRowTableRenderPolicy());
|
builder.bind("分项评估", new CheckInfoTablePolicy());
|
|
var abstractStyle = viewConfig != null && viewConfig.get("检查综合评价情况样式0");
|
builder.bind("data.评估结果.综合信息", new AbstractInfoTablePolicy(abstractStyle ? 0 : 1));
|
builder.addPlugin('%', new CustomPictureRenderPolicy(userFileService));
|
return builder;
|
}
|
|
/**
|
* 初始化模型
|
* @param data 数据
|
* @return 模型
|
*/
|
private Map<String, Object> initModel(JSONObject data){
|
var dataMap = new HashMap<String, Object>();
|
dataMap.put("data", data);
|
dataMap.put("隐患等级分布饼图", buildErrorLevelPieChart(data));
|
dataMap.put("隐患等级分布直方图", buildErrorLevelBarChart(data));
|
|
initChart(data, dataMap);
|
return dataMap;
|
}
|
|
/**
|
* 初始化图表
|
* @param data 数据
|
* @param dataMap 数据映射
|
*/
|
private void initChart(JSONObject data, Map<String, Object> dataMap){
|
var evalResult = data.getJSONObject("评估结果");
|
var checkCategories = evalResult.getJSONArray("检查项");
|
if(checkCategories == null) return;
|
var safetyCategories = new JSONArray();
|
for (var c : checkCategories){
|
var co = (JSONObject)c;
|
var name = co.getString("名称");
|
if(name != null && name.contains("安全"))
|
safetyCategories.add(co);
|
var pieChart = buildPieChart(co);
|
if(pieChart!=null)
|
co.put("问题分布饼图", pieChart);
|
var barChart = buildBarChart(co);
|
if(barChart!=null)
|
co.put("问题分布直方图", barChart);
|
}
|
if(safetyCategories.isEmpty() && !checkCategories.isEmpty())
|
safetyCategories.add(checkCategories.get(0));
|
evalResult.put("安全检查项", safetyCategories);
|
}
|
|
/**
|
* 构建饼图
|
* @param c 数据
|
* @return 饼图
|
*/
|
private ChartSingleSeriesRenderData buildPieChart(JSONObject c) {
|
var name = c.getString("名称");
|
var title = name + "问题分布饼图";
|
|
var checkInfos = getCheckInfos(c);
|
if(CollectionUtils.isEmpty(checkInfos))
|
return null;
|
String [] categories = checkInfos.stream().map( item -> {
|
var obj = (JSONObject)item;
|
return obj.getString("类别") + " " + obj.getString("问题百分比");
|
}).toArray(String[]::new);
|
|
Integer[] values = checkInfos.stream().map( item -> {
|
var obj = (JSONObject)item;
|
return obj.getInteger("问题数量");
|
}).toArray(Integer[]::new);
|
|
return Charts.ofSingleSeries(title, categories)
|
.series("数量", values)
|
.create();
|
}
|
|
/**
|
* 构建柱状图
|
* @param c 数据
|
* @return 柱状图
|
*/
|
private ChartMultiSeriesRenderData buildBarChart(JSONObject c) {
|
var name = c.getString("名称");
|
var title = name + "问题分布直方图";
|
|
var checkInfos = getCheckInfos(c);
|
String [] categories = checkInfos.stream().map( item -> {
|
var obj = (JSONObject)item;
|
return obj.getString("类别");
|
}).toArray(String[]::new);
|
|
Integer[] values = checkInfos.stream().map( item -> {
|
var obj = (JSONObject)item;
|
return obj.getInteger("问题数量");
|
}).toArray(Integer[]::new);
|
|
return Charts.ofBar(title, categories)
|
.addSeries("数量", values)
|
.create();
|
}
|
|
/**
|
* 获取检查信息
|
* @param evalRes 评估结果
|
* @return 检查信息
|
*/
|
private JSONArray getCheckInfos(JSONObject evalRes){
|
var result = new JSONArray();
|
var categoryItems = evalRes.getJSONArray("分项评估");
|
categoryItems.forEach( categoryItem -> {
|
((JSONObject)categoryItem).getJSONArray("分项").forEach( item -> {
|
result.add(item);
|
});
|
});
|
|
return result;
|
}
|
|
// 隐患等级分布饼图
|
/**
|
* 构建隐患等级分布饼图
|
* @param data 数据
|
* @return 隐患等级分布饼图
|
*/
|
private ChartSingleSeriesRenderData buildErrorLevelPieChart(JSONObject data){
|
var title = "隐患等级分布饼图";
|
var checkInfos = data.getJSONObject("评估结果")
|
.getJSONObject("隐患等级分布").getJSONArray("分项");
|
if(checkInfos == null)
|
return null;
|
String [] categories = checkInfos.stream().map( item -> {
|
var obj = (JSONObject)item;
|
return obj.getString("隐患等级") + " " + obj.getString("比例");
|
}).toArray(String[]::new);
|
|
Integer[] values = checkInfos.stream().map( item -> {
|
var obj = (JSONObject)item;
|
return obj.getInteger("数量");
|
}).toArray(Integer[]::new);
|
|
return Charts.ofSingleSeries(title, categories)
|
.series("数量", values)
|
.create();
|
}
|
|
/**
|
* 构建隐患等级分布直方图
|
* @param data 数据
|
* @return 隐患等级分布直方图
|
*/
|
private ChartMultiSeriesRenderData buildErrorLevelBarChart(JSONObject data){
|
var title = "隐患等级分布直方图";
|
var checkInfos = data.getJSONObject("评估结果").getJSONObject("隐患等级分布").getJSONArray("分项");
|
if(checkInfos == null)
|
return null;
|
String [] categories = checkInfos.stream().map( item -> {
|
var obj = (JSONObject)item;
|
return obj.getString("隐患等级") + " " + obj.getString("比例");
|
}).toArray(String[]::new);
|
|
Integer[] values = checkInfos.stream().map( item -> {
|
var obj = (JSONObject)item;
|
return obj.getInteger("数量");
|
}).toArray(Integer[]::new);
|
|
return Charts.ofBar(title, categories)
|
.addSeries("数量", values)
|
.create();
|
}
|
}
|