导出pdf

pom依赖

java 复制代码
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.4.2</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>

代码实现

java 复制代码
package cc.eslink.bu.controller.pc;

import cc.eslink.bu.service.impl.ExportService;
import cc.eslink.bu.util.CurrentUserUtil;
import cc.eslink.common.base.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;


@Api(tags = "导出相关")
@RestController
@RequestMapping("bu/pc/export")
public class ExportController extends BaseController {

    @Resource
    ExportService exportService;

    @ApiOperation(value = "分析报告")
    @GetMapping(value = "/analyzeDoc")
    public HttpServletResponse analyzeDoc1(String month, Long orgId) throws Exception {
        String ownership = CurrentUserUtil.getCurrentUserOwnership();
        String fileName = new String("分析报告".getBytes("GBK"), "ISO8859_1") + ".pdf";
        ServletOutputStream outputStream = response.getOutputStream();
        // 设置响应头信息
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        exportService.exportPdf(ownership, month, orgId, outputStream);
        outputStream.flush();
        outputStream.close();
        return response;
    }

}
java 复制代码
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(data.getCardNo());
            if (null == userInfo) {
                userInfo = new UserInfoDto();
            }
            addRowData(font2, table,
                    new String[]{String.valueOf(row), userInfo.getUserNo(), userInfo.getUserName(), ConvertDataUtil.getMeterAnalyzeResult(data.getResultType()),
                            data.getSuggestTypeDesc(), data.getCaliber()});
        }

        return table;
    }

    private Element createUserCompareDetailTable(List<QueryUcListDto> dataList, BaseFont baseFont) {
        //设置为7列
        //参数 relativeWidths 是一个 float 数组,用于指定每列的相对宽度。
        //在 PdfPTable 中,相对宽度是指相对于表格总宽度的比例。例如,如果数组 {1, 2, 1} 表示三列,其中第二列的宽度是第一列的两倍,第三列的宽度是第一列的一半。
        PdfPTable table = new PdfPTable(new float[]{1, 2, 2, 4, 3, 3, 3});
        //表格宽占page比例
        table.setWidthPercentage(100);
        //字体加粗
        Font font1 = getFont(10, Font.BOLD, baseFont);
        //不加粗
        Font font2 = getFont(8, Font.NORMAL, baseFont);

        //7个一行
        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++) {
            QueryUcListDto data = dataList.get(row - 1);
            addRowData(font2, table,
                    new String[]{String.valueOf(row), data.getUserNo(), data.getCardNo(), data.getUserName(), data.getYcMsg(),
                            data.getScMsg(), data.getMsg()});
        }

        return table;
    }

    private Element createScoreDetailTable(List<CardScoreDetailDto> dataList, Map<String, UserInfoDto> cardMap, BaseFont baseFont) {
        //设置为7列
        //参数 relativeWidths 是一个 float 数组,用于指定每列的相对宽度。
        //在 PdfPTable 中,相对宽度是指相对于表格总宽度的比例。例如,如果数组 {1, 2, 1} 表示三列,其中第二列的宽度是第一列的两倍,第三列的宽度是第一列的一半。
        PdfPTable table = new PdfPTable(new float[]{1, 2, 2, 4, 2, 2, 2});
        //表格宽占page比例
        table.setWidthPercentage(100);
        //字体加粗
        Font font1 = getFont(10, Font.BOLD, baseFont);
        //不加粗
        Font font2 = getFont(8, Font.NORMAL, baseFont);

        //7个一行
        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++) {
            CardScoreDetailDto 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(), data.getCardNo(), data.getSiteName(),String.format("%.2f", data.getAvgScore()),
                            intToString(data.getMaxScore()), intToString(data.getMinScore())});
        }

        return table;
    }

    private String intToString(Integer a) {
        return a == null ? "" : String.valueOf(a);
    }

    /**
     * 获取基本信息table
     */
    public PdfPTable createBaseInfoTable(WordExportDataDto allData, String month, BaseFont baseFont) {
        //设置表格列数
        PdfPTable table = new PdfPTable(2);
        Font font = getFont(12, Font.BOLD, baseFont);
        //两个一行
        table.addCell(createCellNoBorder("公司名称: " + allData.getGsmc(), font));
        table.addCell(createCellNoBorder("数据时间范围: " + month, font));

        table.addCell(createCellNoBorder("大用户数量: " + allData.getScyhsl(), font));
        table.addCell(createCellNoBorder("表具数量: " + allData.getScbksl(), font));

        table.addCell(createCellNoBorder("远传用户数量: " + allData.getYcyhsl(), font));
        table.addCell(createCellNoBorder("远传表具数量: " + allData.getYcbksl(), font));

        table.addCell(createCellNoBorder("异常用户数量: " + allData.getYycyhsl(), font));
        table.addCell(createCellNoBorder("异常表具数量: " + allData.getYycbksl(), font));

        return table;
    }

    /**
     * 逐行添加数据
     *
     * @author wxj
     * @date 2024/3/13 10:36
     **/
    private void addRowData(Font font, PdfPTable table, String[] rowData) {
        for (String data : rowData) {
            table.addCell(createNormalCell(data, font));
        }
    }

    private Paragraph createTitle(String content, BaseFont baseFont) {
        //Font.BOLD-字体加粗
        Font font = getFont(18, Font.BOLD, baseFont);
        Paragraph paragraph = createParagraph(content, font, 15);
        // 设置段落居中
        paragraph.setAlignment(Element.ALIGN_CENTER);
        return paragraph;
    }


    private Paragraph createChapterH1(String content, BaseFont baseFont) {
        //Font.BOLD-字体加粗
        Font font = getFont(18, Font.BOLD, baseFont);
        Paragraph paragraph = createParagraph(content, font, 15);
        // 设置段落居左
        paragraph.setAlignment(Element.ALIGN_LEFT);
        return paragraph;
    }

    private Paragraph createChapterH2(String content, BaseFont baseFont) {
        //Font.BOLD-字体加粗
        Font font = getFont(12, Font.BOLD, baseFont);
        Paragraph paragraph = createParagraph(content, font, 15);
        // 设置段落居左
        paragraph.setAlignment(Element.ALIGN_LEFT);
        return paragraph;
    }

    private Paragraph createParagraph(String content, Font font, float num) {
        Paragraph paragraph = new Paragraph(content, font);
        // 设置段落的前置间距。这意味着在段落之前将会有一个与行高相等的间距
        paragraph.setSpacingBefore(num);
        // 设置段落的后置间距。这意味着在段落之后将会有一个与行高相等的间距。
        paragraph.setSpacingAfter(num);
        return paragraph;
    }

    private static Font getFont(float size, int style, BaseFont baseFont) {
        return new Font(baseFont, size, style);
    }

    private static BaseFont getBaseFont() {
        BaseFont baseFont = null;
        try {
            ClassPathResource classPathResource = new ClassPathResource("fonts/simsun.ttc");
            // 宋体后面要加,0 或者,1
            baseFont = BaseFont.createFont(classPathResource.getURL().toString() + ",1", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        } catch (Exception e) {
            bizLogger.error("getBaseFont error", e);
        }
        return baseFont;
    }

    /**
     * 创建单元格 隐藏表格所有框线
     *
     * @param content 文本
     * @param font    字体
     * @return PdfPCell
     * @author wxj
     * @date 2024/3/13 9:56
     **/
    private PdfPCell createCellNoBorder(String content, Font font) {
        PdfPCell cell = new PdfPCell(createParagraph(content, font, 15));
        // 将单元格内容的水平对齐方式设置为居左对齐
        cell.setHorizontalAlignment(PdfPCell.ALIGN_LEFT);
        // 将单元格内容的垂直对齐方式设置为居中对齐
        cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
        // 设置单元格内容与边框的填充距离
        cell.setPadding(10f);
        //设置为无边框
        cell.setBorder(PdfPCell.NO_BORDER);
        return cell;
    }

    /**
     * 设置单元格正文格式
     *
     * @author wxj
     * @date 2024/3/13 10:57
     **/
    private PdfPCell createNormalCell(String content, Font font) {
        PdfPCell cell = new PdfPCell(createParagraph(content, font, 10));
        // 设置单元格内容与边框的填充距离
        cell.setPadding(8f);
        // 将单元格内容的水平对齐方式设置为居中对齐
        cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
        // 将单元格内容的垂直对齐方式设置为居中对齐
        cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
        // 设置单元格的边框宽度为2个单位
//        cell.setBorderWidth(1f);
        // 设置单元格的边框颜色为黑色
        cell.setBorderColor(BaseColor.BLACK);
        return cell;
    }

    /**
     * 创建单元格 单元格加背景色
     *
     * @param content 文本
     * @param font    字体
     * @return String
     * @author wxj
     * @date 2024/3/13 10:17
     **/
    private PdfPCell createTitleCell(String content, Font font) {
        PdfPCell cell = new PdfPCell(createParagraph(content, font, 10));
        // 设置单元格内容与边框的填充距离
        cell.setPadding(10f);
        // 将单元格内容的水平对齐方式设置为居中对齐
        cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
        // 将单元格内容的垂直对齐方式设置为居中对齐
        cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
        // 设置单元格的边框宽度为2个单位
//        cell.setBorderWidth(1f);
        // 设置单元格的边框颜色为黑色
        cell.setBorderColor(BaseColor.BLACK);
        // 设置单元格的背景颜色为浅灰色
        cell.setBackgroundColor(BaseColor.LIGHT_GRAY);
        return cell;
    }

    /**
     * 准备所有需要的数据
     *
     * @param ownership 租户号
     * @param month     月份
     * @param orgIds    组织id
     * @return WordExportDataDto
     */
    private WordExportDataDto getAllData(String ownership, String month, List<Long> orgIds) {

        Organization rootOrg = organizationService.getRootOrg(ownership);

        List<UserInfoDto> mannualUserList = userInfoDao.getMannualUserList(ownership, orgIds);
        Map<String, UserInfoDto> cardsMap = mannualUserList.stream().collect(Collectors.toMap(UserInfoDto::getCardNo, Function.identity(), (v1, v2) -> v1));
        long scyhsl = mannualUserList.stream().filter(x -> StringUtils.isNotBlank(x.getUserNo())).map(UserInfoDto::getUserNo).distinct().count();
        long scbksl = mannualUserList.stream().filter(x -> StringUtils.isNotBlank(x.getCardNo())).map(UserInfoDto::getCardNo).distinct().count();

        long ycyhsl = mannualUserList.stream().filter(x -> StringUtils.isNotBlank(x.getUserNo()) && StringUtils.isNotBlank(x.getSiteCode()))
                .map(UserInfoDto::getUserNo).distinct().count();
        long ycbksl = mannualUserList.stream().filter(x -> StringUtils.isNotBlank(x.getCardNo()) && StringUtils.isNotBlank(x.getSiteCode()))
                .map(UserInfoDto::getCardNo).distinct().count();
        //异常1:超期服役异常:当月,手抄,分析结论不为空的,拿到cardNo信息
        List<OverTimeUser> overTimeUserCardNos = overTimeUserDao.getOverTimeUserCardNos(ownership, month, orgIds);
        Set<String> overTimeCards = overTimeUserCardNos.stream().map(OverTimeUser::getCardNo).collect(Collectors.toSet());
        //异常2:水表选型异常:meter_type_analyze表中,异常记录结论是那几个的,捞出site_code,继续去userBound表中比对出cardNo
        List<MeterTypeAnalyze> meterTypeAnalyzeCardNos = meterTypeAnalyzeDao.getMeterTypeAnalyzeCardNos(ownership, month, orgIds);
        List<String> siteCodes = meterTypeAnalyzeCardNos.stream().map(MeterTypeAnalyze::getSiteCode).collect(Collectors.toList());
        //拿到cardNo信息
        List<UserBound> userBounds = getUserBounds(ownership, siteCodes);
        Set<String> meterTypeCards = userBounds.stream().map(UserBound::getCardNo).collect(Collectors.toSet());
        //异常3:用户对比异常:当月,标志是1,拿到cardNo信息
        List<UserComparison> userCompareCardNos = userComparisonDao.getUserCompareCardNos(ownership, month, orgIds);
        Map<Integer, List<UserComparison>> userComTypeMap = userCompareCardNos.stream().collect(Collectors.groupingBy(UserComparison::getMtType));
        Set<String> userCompareCards = userCompareCardNos.stream().map(UserComparison::getMtCode).collect(Collectors.toSet());
        Set<String> yycCards = new HashSet<>();
        yycCards.addAll(overTimeCards);
        yycCards.addAll(meterTypeCards);
        yycCards.addAll(userCompareCards);
        //异常用户
        long allYcUsers = overTimeUserCardNos.stream().filter(a -> yycCards.contains(a.getCardNo())).distinct().count();

        //获取用户分值详情信息
        QueryScoreMapDto queryScoreMapDto = singlePointAnalysisService.queryMonthAvgScoreMap(ownership, month, orgIds);

        Set<String> cardNos = cardsMap.keySet();
        //手抄用户数量
        WordExportDataDto wordExportDataDto = new WordExportDataDto();
        wordExportDataDto.setGsmc(rootOrg.getNodeName());
        wordExportDataDto.setCardMap(cardsMap);
        wordExportDataDto.setScyhsl(String.valueOf(scyhsl));
        wordExportDataDto.setScbksl(String.valueOf(scbksl));
        wordExportDataDto.setYcyhsl(String.valueOf(ycyhsl));
        wordExportDataDto.setYcbksl(String.valueOf(ycbksl));
        wordExportDataDto.setYycyhsl(String.valueOf(allYcUsers));
        wordExportDataDto.setYycbksl(String.valueOf(yycCards.size()));
        overTimeUserCardNos = overTimeUserCardNos.stream().filter(a -> cardNos.contains(a.getCardNo())).collect(Collectors.toList());
        wordExportDataDto.setCqfyycsl(String.valueOf(overTimeUserCardNos.size()));
        wordExportDataDto.setCqfyycList(overTimeUserCardNos);
        meterTypeAnalyzeCardNos = meterTypeAnalyzeCardNos.stream().filter(a -> cardNos.contains(a.getCardNo())).collect(Collectors.toList());
        wordExportDataDto.setSbxxycsl(String.valueOf(meterTypeCards.size()));
        wordExportDataDto.setSbxxycList(meterTypeAnalyzeCardNos);
        wordExportDataDto.setYhdbycycsl(String.valueOf(CollectionUtils.isEmpty(userComTypeMap.get(1)) ? 0 : userComTypeMap.get(1).size()));
        wordExportDataDto.setYhdbscycsl(String.valueOf(CollectionUtils.isEmpty(userComTypeMap.get(2)) ? 0 : userComTypeMap.get(2).size()));
        wordExportDataDto.setYhdbycscycsl(String.valueOf(CollectionUtils.isEmpty(userComTypeMap.get(3)) ? 0 : userComTypeMap.get(3).size()));
        List<QueryUcListDto> userCompareList = userComparisonDao.queryUcList(ownership, month, null, null, 4, null, orgIds);
        wordExportDataDto.setYhdbList(userCompareList);
        wordExportDataDto.setQueryScoreMapDto(queryScoreMapDto);
        return wordExportDataDto;
    }

    public List<UserBound> getUserBounds(String ownership, List<String> siteCodes) {
        if (CollectionUtils.isEmpty(siteCodes)) {
            return new ArrayList<>();
        }
        //查询已绑定的表卡编号
        Example example = new Example(UserBound.class);
        example.createCriteria()
                .andEqualTo("ownership", ownership)
                .andIn("siteCode", siteCodes);
        return userBoundDao.selectByExample(example);
    }

}

设置字体

windows系统字体文件夹

C:\Windows\Fonts

中文字体对应文件名

设置字体

将字体文件放到resource文件夹下
配置字体

宋体后面要加,0 或者,1

java 复制代码
ClassPathResource classPathResource = new ClassPathResource("fonts/simsun.ttc");
// 宋体后面要加,0 或者,1
BaseFont  baseFont = BaseFont.createFont(classPathResource.getURL().toString() + ",1", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

其它字体则正常配置

java 复制代码
//华文细黑
ClassPathResource classPathResource = new ClassPathResource("fonts/STXIHEI.TTF");
BaseFont  baseFont = BaseFont.createFont(classPathResource.getURL().toString(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
java 复制代码
    private static Font getFont(float size, int style, BaseFont baseFont) {
        return new Font(baseFont, size, style);
    }

    private static BaseFont getBaseFont() {
        BaseFont baseFont = null;
        try {
            ClassPathResource classPathResource = new ClassPathResource("fonts/simsun.ttc");
            // 宋体后面要加,0 或者,1
            baseFont = BaseFont.createFont(classPathResource.getURL().toString() + ",1", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        } catch (Exception e) {
            bizLogger.error("getBaseFont error", e);
        }
        return baseFont;
    }

参考连接

https://blog.csdn.net/AiElk/article/details/126482802

https://www.cnblogs.com/whalesea/p/11776463.html

https://pdai.tech/md/spring/springboot/springboot-x-file-pdf-itext.html

https://developer.aliyun.com/article/672841

https://blog.csdn.net/qq_29856789/article/details/80883301

相关推荐
知难行难17 小时前
福昕阅读器高级版解决文件上传IEEE PDF eXpress字体未嵌入
pdf·express
子非吾喵18 小时前
在Element Ui中支持从系统粘贴版中获取图片和PDF,Docx,Doc,PPT等文档
ui·pdf·powerpoint
有过~1 天前
WPS Office手机去广高级版
pdf·wps
幸福清风2 天前
PymuPDF4llm提取pdf文件文字、表格与图片
pdf
zhentiya2 天前
王珊数据库系统概论第六版PDF+第五版课后答案+课件
数据库·pdf
大大大反派3 天前
ONLYOFFICE 8.2深度测评:集成PDF编辑、数据可视化与AI功能的强大办公套件
人工智能·信息可视化·pdf
zhentiya3 天前
濮良贵《机械设计》第十版课后习题答案全解PDF电子版
pdf
理竹子3 天前
Typora导出pdf手动分页和设置字体样式
pdf·typora·markdown
七夕先生3 天前
Qt:QPdfDocument渲染PDF文件时的信息丢失问题
c++·qt·pdf
咘噜biu3 天前
PDF模板制作与填充(Java)
java·pdf·pdf模板