导出pdf
package cc.eslink.bu.service.impl;
import cc.eslink.bu.dao.bu.*;
import cc.eslink.bu.domain.dto.*;
import cc.eslink.bu.domain.entity.*;
import cc.eslink.bu.service.OrganizationService;
import cc.eslink.bu.service.SinglePointAnalysisService;
import cc.eslink.bu.util.BigDecimalUtil;
import cc.eslink.bu.util.ConvertDataUtil;
import cc.eslink.bu.util.InfluxHttpService;
import cc.eslink.common.base.BaseLogable;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import java.util.*;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @author : wxj
* @date : 2024/3/13 9:28
*/
@Service("exportService")
public class ExportService extends BaseLogable {
@Resource
private OrganizationService organizationService;
@Resource
private SinglePointAnalysisService singlePointAnalysisService;
@Resource
private InfluxHttpService influxHttpService;
@Resource
private UserInfoDao userInfoDao;
@Resource
private UserBoundDao userBoundDao;
@Resource
private OverTimeUserDao overTimeUserDao;
@Resource
private MeterTypeAnalyzeDao meterTypeAnalyzeDao;
@Resource
private UserComparisonDao userComparisonDao;
public void exportPdf(String ownership, String month, Long orgId, ServletOutputStream outputStream) {
try {
List<Long> orgIds = influxHttpService.getOrgIds(orgId, ownership);
//创建文档
Document document = new Document();
//绑定输出流
PdfWriter.getInstance(document, outputStream);
//打开文档
document.open();
BaseFont baseFont = getBaseFont();
// Title
document.add(createTitle("大用户水表诊断报告", baseFont));
document.add(createChapterH1("一、基本信息", baseFont));
//准备所有数据
WordExportDataDto allData = getAllData(ownership, month, orgIds);
//添加基本信息表格
document.add(createBaseInfoTable(allData, month, baseFont));
document.add(createChapterH1("二、异常总览", baseFont));
document.add(createChapterH2("》异常类型评估", baseFont));
document.add(createExceptionTypeTable(allData, baseFont));
document.add(createChapterH2("》用户分值评估", baseFont));
document.add(createUserScoresTable(allData.getQueryScoreMapDto().getScoreList(), baseFont));
document.add(createChapterH1("三、异常明细", baseFont));
document.add(createChapterH2("》超期服役", baseFont));
document.add(createOverTimeUserDetailTable(allData.getCqfyycList(), allData.getCardMap(), baseFont));
document.add(createChapterH2("》水表选型", baseFont));
document.add(createMeterTypeDetailTable(allData.getSbxxycList(), allData.getCardMap(), baseFont));
document.add(createChapterH2("》用户对比", baseFont));
document.add(createUserCompareDetailTable(allData.getYhdbList(), baseFont));
document.add(createChapterH1("四、评分明细", baseFont));
document.add(createScoreDetailTable(allData.getQueryScoreMapDto().getCardList(), allData.getCardMap(), baseFont));
document.close();
} catch (Exception e) {
bizLogger.error("导出报错", e);
}
}
private PdfPTable createExceptionTypeTable(WordExportDataDto allData, BaseFont baseFont) {
//设置为5列
//参数 relativeWidths 是一个 float 数组,用于指定每列的相对宽度。
//在 PdfPTable 中,相对宽度是指相对于表格总宽度的比例。例如,如果数组 {1, 2, 1} 表示三列,其中第二列的宽度是第一列的两倍,第三列的宽度是第一列的一半。
PdfPTable table = new PdfPTable(new float[]{1, 4, 2, 2, 2});
//表格宽占page比例
table.setWidthPercentage(100);
//字体加粗
Font font1 = getFont(12, Font.BOLD, baseFont);
//不加粗
Font font2 = getFont(10, Font.NORMAL, baseFont);
//五个一行
table.addCell(createTitleCell("序号", font1));
table.addCell(createTitleCell("异常分类", font1));
table.addCell(createTitleCell("用户数量", font1));
table.addCell(createTitleCell("表具数量", font1));
table.addCell(createTitleCell("异常表具", font1));
addRowData(font2, table, new String[]{"1", "超期服役", allData.getScyhsl(), allData.getScbksl(), allData.getCqfyycsl()});
addRowData(font2, table, new String[]{"2", "水表选型", allData.getYcyhsl(), allData.getYcbksl(), allData.getSbxxycsl()});
addRowData(font2, table, new String[]{"3", "用户对比-远传数据对比", allData.getYcyhsl(), allData.getYcbksl(), allData.getYhdbycycsl()});
addRowData(font2, table, new String[]{"4", "用户对比-手抄数据对比", allData.getScyhsl(), allData.getScbksl(), allData.getYhdbscycsl()});
addRowData(font2, table, new String[]{"5", "用户对比-远传/手抄对比", allData.getYcyhsl(), allData.getYcbksl(), allData.getYhdbycscycsl()});
return table;
}
private Element createUserScoresTable(List<ComprehensiveScoreDetailDto> scoreList, BaseFont baseFont) {
//设置为4列
//参数 relativeWidths 是一个 float 数组,用于指定每列的相对宽度。
//在 PdfPTable 中,相对宽度是指相对于表格总宽度的比例。例如,如果数组 {1, 2, 1} 表示三列,其中第二列的宽度是第一列的两倍,第三列的宽度是第一列的一半。
PdfPTable table = new PdfPTable(new float[]{1, 4, 2, 2});
//表格宽占page比例
table.setWidthPercentage(100);
//字体加粗
Font font1 = getFont(12, Font.BOLD, baseFont);
//不加粗
Font font2 = getFont(10, Font.NORMAL, baseFont);
//4个一行
table.addCell(createTitleCell("序号", font1));
table.addCell(createTitleCell("分值区间(月均)", font1));
table.addCell(createTitleCell("分析意见", font1));
table.addCell(createTitleCell("表具数量", font1));
// 填充表格内容
for (int i = 1; i <= scoreList.size(); i++) {
ComprehensiveScoreDetailDto score = scoreList.get(i - 1);
addRowData(font2, table, new String[]{String.valueOf(i), score.getScoreStr(), score.getRemark(), intToString(score.getNum())});
}
return table;
}
private Element createOverTimeUserDetailTable(List<OverTimeUser> dataList, Map<String, UserInfoDto> cardMap, BaseFont baseFont) {
//设置为8列
//参数 relativeWidths 是一个 float 数组,用于指定每列的相对宽度。
//在 PdfPTable 中,相对宽度是指相对于表格总宽度的比例。例如,如果数组 {1, 2, 1} 表示三列,其中第二列的宽度是第一列的两倍,第三列的宽度是第一列的一半。
PdfPTable table = new PdfPTable(new float[]{1, 2, 3, 3, 2, 2, 3, 3});
//表格宽占page比例
table.setWidthPercentage(100);
//字体加粗
Font font1 = getFont(10, Font.BOLD, baseFont);
//不加粗
Font font2 = getFont(8, Font.NORMAL, baseFont);
//8个一行
table.addCell(createTitleCell("序号", font1));
table.addCell(createTitleCell("用户号", font1));
table.addCell(createTitleCell("用户名称", font1));
table.addCell(createTitleCell("下次换表时间", font1));
table.addCell(createTitleCell("超期服役", font1));
table.addCell(createTitleCell("月均变化", font1));
table.addCell(createTitleCell("分析结论", font1));
table.addCell(createTitleCell("确认意见", font1));
for (int row = 1; row <= dataList.size(); row++) {
OverTimeUser data = dataList.get(row - 1);
UserInfoDto userInfo = cardMap.get(data.getCardNo());
if (null == userInfo) {
userInfo = new UserInfoDto();
}
addRowData(font2, table,
new String[]{String.valueOf(row), userInfo.getUserNo(), userInfo.getUserName(), data.getNextChangeTime(), "是",
BigDecimalUtil.setScaleToString(data.getYjysbh(), 2, null, ""), data.getFxjl(), data.getQryj()});
}
return table;
}
private Element createMeterTypeDetailTable(List<MeterTypeAnalyze> dataList, Map<String, UserInfoDto> cardMap, BaseFont baseFont) {
//设置为6列
//参数 relativeWidths 是一个 float 数组,用于指定每列的相对宽度。
//在 PdfPTable 中,相对宽度是指相对于表格总宽度的比例。例如,如果数组 {1, 2, 1} 表示三列,其中第二列的宽度是第一列的两倍,第三列的宽度是第一列的一半。
PdfPTable table = new PdfPTable(new float[]{1, 2, 2, 2, 2, 2});
//表格宽占page比例
table.setWidthPercentage(100);
//字体加粗
Font font1 = getFont(10, Font.BOLD, baseFont);
//不加粗
Font font2 = getFont(8, Font.NORMAL, baseFont);
//6个一行
table.addCell(createTitleCell("序号", font1));
table.addCell(createTitleCell("用户号", font1));
table.addCell(createTitleCell("用户名称", font1));
table.addCell(createTitleCell("分析结论", font1));
table.addCell(createTitleCell("推荐型号", font1));
table.addCell(createTitleCell("当前口径", font1));
for (int row = 1; row <= dataList.size(); row++) {
MeterTypeAnalyze data = dataList.get(row - 1);
UserInfoDto userInfo = cardMap.get