最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot將業(yè)務(wù)模塊數(shù)據(jù)導(dǎo)出為PDF的示例代碼

 更新時間:2026年04月28日 09:04:32   作者:瑪卡巴卡ldf  
在管理系統(tǒng)開發(fā)中,經(jīng)常會遇到這樣一類需求:頁面展示的是數(shù)據(jù)庫中的業(yè)務(wù)數(shù)據(jù),用戶希望把這些數(shù)據(jù)導(dǎo)出成正式的 PDF 打印單,列表頁可以勾選多條,導(dǎo)出成一個 PDF 文件等需求,本文就給大家介紹了SpringBoot將業(yè)務(wù)模塊數(shù)據(jù)導(dǎo)出為PDF的方法步驟,需要的朋友可以參考下

問題:在管理系統(tǒng)開發(fā)中,經(jīng)常會遇到這樣一類需求:

  • 頁面展示的是數(shù)據(jù)庫中的業(yè)務(wù)數(shù)據(jù)
  • 用戶希望把這些數(shù)據(jù)導(dǎo)出成正式的 PDF 打印單
  • 一條業(yè)務(wù)數(shù)據(jù)是一張單據(jù)
  • 列表頁可以勾選多條,導(dǎo)出成一個 PDF 文件
  • PDF 上半部分展示主表唯一信息
  • PDF 下半部分展示這條業(yè)務(wù)對應(yīng)的多條明細(xì)記錄
  • 導(dǎo)出后還希望保存到附件表,便于追溯和下載

一、需求拆解

這次實現(xiàn)的業(yè)務(wù)背景是:

  • 主表:t_reagent
  • 明細(xì)表:t_reagent_record
  • 領(lǐng)用接口:/control/reagent/receiveReagents
  • 新增導(dǎo)出接口:/control/reagent/exportPrintPdf

導(dǎo)出的 PDF 頁面結(jié)構(gòu)如下:

上半部分展示試劑唯一信息:物料名稱、物料貨號、物料分類、物料類型、規(guī)格、型號、批號、生產(chǎn)商、品牌、存儲條件、現(xiàn)庫存量、保管人、備注

下半部分展示這條試劑對應(yīng)的多條操作記錄:操作類型、操作時間、數(shù)量、單位、單價、部門操作人、批號、備注、審核人

實現(xiàn):單條導(dǎo)出、批量導(dǎo)出多條數(shù)據(jù)、合并到同一個 PDF 中、可選保存到附件表 t_base_file

二、如何設(shè)計

拆成四步,為了可復(fù)用不可合并一步

Controller
-> Service
-> Assembler(組裝器)
-> PDF Render Tool(渲染工具)
-> Optional Attachment Save(可選附件保存)

三、整體架構(gòu)圖

前端 / ApiPost
    |
    | POST /control/reagent/exportPrintPdf
    v
ReagentController
    |
    v
ReagentServiceImpl.exportPrintPdf(...)
    |
    |-- 查詢 t_reagent 主表
    |-- 查詢 t_reagent_record 明細(xì)表
    |-- 按 reagentId 分組
    v
ReagentPrintAssembler
    |
    |-- 組裝 ReagentPrintDTO
    v
PdfRenderUtil
    |
    |-- 生成 PDF byte[]
    |
    |-- 可選:保存到 t_base_file
    v
HttpServletResponse 輸出 PDF 下載

四、加 PDF 依賴

<dependency>
    <groupId>com.github.librepdf</groupId>
    <artifactId>openpdf</artifactId>
    <version>1.3.39</version>
</dependency>

五、接口設(shè)計

basemanage/platform/main/reagent/controller/ReagentController.java

新增接口

@PostMapping("/exportPrintPdf")
void exportPrintPdf(@RequestBody ReagentPrintRequest request, HttpServletResponse response);

請求對象

文件位置:

basemanage/platform/main/reagent/bean/ReagentPrintRequest.java

@Data
public class ReagentPrintRequest {
    private List<String> ids;
    private Boolean saveAttachment;
}

請求示例

{
  "ids": ["試劑主表ID1", "試劑主表ID2"],
  "saveAttachment": true
}

這里傳的是t_reagent.id,不是t_reagent_record.id。

六、為什么接口返回void

一開始很容易寫成這樣:

JsonResult exportPrintPdf(...)

但這個接口本質(zhì)是文件下載接口,而不是普通 JSON 接口。

如果你一邊往HttpServletResponse輸出 PDF,一邊又返回JsonResult,在@RestController環(huán)境下很容易出現(xiàn):

  • 二次寫響應(yīng)
  • 文件流和 JSON 混在一起
  • 前端下載失敗

所以最后改成:

void exportPrintPdf(...)

Controller 實現(xiàn)如下。

文件位置

basemanage/platform/main/reagent/controller/ReagentControllerImpl.java

@Override
public void exportPrintPdf(ReagentPrintRequest request, HttpServletResponse response) {
    getService().exportPrintPdf(request, response);
}

七、Service 接口定義

basemanage/platform/main/reagent/service/ReagentService.java

void exportPrintPdf(ReagentPrintRequest request, HttpServletResponse response);

八、批量查詢明細(xì)記錄

因為是批量導(dǎo)出,所以一定不要一條試劑查一次記錄,那樣很容易變成 N+1 查詢。

正確做法是:

  1. 一次查所有主表數(shù)據(jù)
  2. 一次查所有記錄數(shù)據(jù)
  3. 內(nèi)存里按reagentId分組

所以先給ReagentRecordMapper增加一個批量查詢方法。

1. Mapper 接口

文件位置:

basemanage/platform/main/reagent/dao/ReagentRecordMapper.java

List<ReagentRecordBean> selectListByReagentIds(@Param("reagentIds") List<String> reagentIds);

2. Mapper XML

文件位置:

src/main/resources/mapper/ReagentRecordMapper.xml

<select id="selectListByReagentIds" resultType="com.px.basemanage.platform.main.reagent.bean.ReagentRecordBean">
    select t.*, r.batchNo
    from t_reagent_record t
    left join t_reagent r on r.id = t.reagentId
    where t.reagentId in
    <foreach collection="reagentIds" item="reagentId" open="(" close=")" separator=",">
        #{reagentId}
    </foreach>
    order by t.reagentId, t.operateTime desc, t.createTime desc
</select>

為什么這里聯(lián)查了t_reagent

因為ReagentRecordBean里有一個非持久化字段:

@TableField(exist = false)
private String batchNo;

這樣在打印記錄時,可以直接展示批號。

九、定義打印用 DTO,而不是直接拿實體渲染

不要直接拿 ReagentBean 和 ReagentRecordBean 去畫 PDF,而應(yīng)該先定義打印模型。

1. 打印主 DTO

basemanage/platform/main/reagent/service/ReagentPrintAssembler.java

@Data
public class ReagentPrintDTO {
    private String title;
    private String reagentId;
    private List<Map.Entry<String, String>> summaryFields = new ArrayList<>();
    private List<ReagentPrintRecordDTO> records = new ArrayList<>();
}

2. 打印明細(xì) DTO

文件位置:

basemanage/platform/main/reagent/bean/ReagentPrintRecordDTO.java

@Data
public class ReagentPrintRecordDTO {
    private String operateType;
    private String operateTime;
    private String reagentNumber;
    private String reagentUnit;
    private String reagentPrice;
    private String deptName;
    private String operater;
    private String batchNo;
    private String remark;
    private String handledUserName;
    private String auditUserName;
}

優(yōu)點:

  1. 實體和打印結(jié)構(gòu)解耦
  2. 字段格式化集中處理
  3. 后續(xù) PDF 工具就不依賴具體業(yè)務(wù)表
  4. 以后可以復(fù)用到別的模塊

十、用 Assembler 組裝打印字段

這一層專門負(fù)責(zé)把數(shù)據(jù)庫對象轉(zhuǎn)成打印對象。

basemanage/core/pdf/PdfRenderUtil.java

@Component
public class ReagentPrintAssembler {
    private static final DateTimeFormatter DATETIME_FORMATTER =
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    public ReagentPrintDTO assemble(ReagentBean reagentBean, List<ReagentRecordBean> recordBeans) {
        ReagentPrintDTO dto = new ReagentPrintDTO();
        dto.setTitle("試劑領(lǐng)用打印單");
        dto.setReagentId(reagentBean.getId());

        addField(dto, "物料名稱", reagentBean.getReagentName());
        addField(dto, "物料貨號", reagentBean.getReagentNo());
        addField(dto, "物料分類", reagentBean.getReagentClass());
        addField(dto, "物料類型", reagentBean.getReagentType());
        addField(dto, "規(guī)格型號", reagentBean.getSpecification());
        addField(dto, "批號", reagentBean.getBatchNo());
        addField(dto, "生產(chǎn)商", reagentBean.getManufacturer());
        addField(dto, "品牌", reagentBean.getReagentBrand());
        addField(dto, "存儲條件", reagentBean.getStorageCondition());
        addField(dto, "試劑形態(tài)", reagentBean.getReagentShape());
        addField(dto, "供應(yīng)商", reagentBean.getSupplier());
        addField(dto, "有效期", reagentBean.getValidityDate());
        addField(dto, "現(xiàn)庫存量", formatNumber(reagentBean.getInventoryCount()));
        addField(dto, "數(shù)量單位", reagentBean.getInventoryUnit());
        addField(dto, "保管人", reagentBean.getCustodianName());
        addField(dto, "備注", reagentBean.getRemark());

        dto.setRecords(recordBeans.stream().map(this::toRecordDto).collect(Collectors.toList()));
        return dto;
    }

    private ReagentPrintRecordDTO toRecordDto(ReagentRecordBean bean) {
        ReagentPrintRecordDTO dto = new ReagentPrintRecordDTO();
        dto.setOperateType(bean.getOperateType());
        dto.setOperateTime(bean.getOperateTime() == null ? "--" : bean.getOperateTime().format(DATETIME_FORMATTER));
        dto.setReagentNumber(formatNumber(bean.getReagentNumber()));
        dto.setReagentUnit(defaultText(bean.getReagentUnit()));
        dto.setReagentPrice(formatNumber(bean.getReagentPrice()));
        dto.setDeptName(defaultText(bean.getDeptName()));
        dto.setOperater(defaultText(bean.getOperater()));
        dto.setBatchNo(defaultText(bean.getBatchNo()));
        dto.setRemark(defaultText(bean.getRemark()));
        dto.setHandledUserName(defaultText(bean.getHandledUserName()));
        dto.setAuditUserName(defaultText(bean.getAuditUserName()));
        return dto;
    }

    private void addField(ReagentPrintDTO dto, String label, String value) {
        dto.getSummaryFields().add(new AbstractMap.SimpleEntry<>(label, defaultText(value)));
    }

    private String formatNumber(Double value) {
        return value == null ? "--" : String.valueOf(value);
    }

    private String defaultText(String value) {
        return value == null || value.trim().isEmpty() ? "--" : value;
    }
}

十一、封裝通用 PDF 渲染工具

這是整套功能里最值得沉淀復(fù)用的部分

basemanage/core/pdf/PdfRenderUtil.java

public final class PdfRenderUtil {
    private PdfRenderUtil() {
    }

    public static byte[] renderReagentPrintPdf(List<ReagentPrintDTO> documents) {
        try {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            Document document = new Document(PageSize.A4, 32, 32, 36, 36);
            PdfWriter.getInstance(document, outputStream);
            document.open();

            BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            Font titleFont = new Font(baseFont, 16, Font.BOLD);
            Font labelFont = new Font(baseFont, 10, Font.BOLD);
            Font valueFont = new Font(baseFont, 10, Font.NORMAL);
            Font tableHeadFont = new Font(baseFont, 9, Font.BOLD);
            Font tableBodyFont = new Font(baseFont, 9, Font.NORMAL);

            for (int i = 0; i < documents.size(); i++) {
                ReagentPrintDTO doc = documents.get(i);
                if (i > 0) {
                    document.newPage();
                }

                Paragraph title = new Paragraph(doc.getTitle(), titleFont);
                title.setAlignment(Element.ALIGN_CENTER);
                title.setSpacingAfter(10f);
                document.add(title);

                PdfPTable summaryTable = new PdfPTable(4);
                summaryTable.setWidthPercentage(100);
                summaryTable.setWidths(new float[]{15f, 35f, 15f, 35f});
                summaryTable.setSpacingAfter(12f);

                for (Map.Entry<String, String> entry : doc.getSummaryFields()) {
                    summaryTable.addCell(createCell(entry.getKey(), labelFont, new Color(242, 242, 242)));
                    summaryTable.addCell(createCell(entry.getValue(), valueFont, Color.WHITE));
                }

                if (doc.getSummaryFields().size() % 2 != 0) {
                    summaryTable.addCell(createCell("", labelFont, Color.WHITE));
                    summaryTable.addCell(createCell("", valueFont, Color.WHITE));
                }

                document.add(summaryTable);

                Paragraph recordTitle = new Paragraph("領(lǐng)用記錄", labelFont);
                recordTitle.setSpacingAfter(8f);
                document.add(recordTitle);

                PdfPTable recordTable = new PdfPTable(10);
                recordTable.setWidthPercentage(100);
                recordTable.setWidths(new float[]{10f, 16f, 9f, 7f, 8f, 12f, 10f, 9f, 12f, 7f});

                addHeader(recordTable, tableHeadFont,
                        "操作類型", "操作時間", "數(shù)量", "單位", "單價", "部門", "操作人", "批號", "備注", "審核人");

                if (doc.getRecords().isEmpty()) {
                    PdfPCell emptyCell = createCell("暫無領(lǐng)用記錄", tableBodyFont, Color.WHITE);
                    emptyCell.setColspan(10);
                    emptyCell.setHorizontalAlignment(Element.ALIGN_CENTER);
                    emptyCell.setMinimumHeight(28f);
                    recordTable.addCell(emptyCell);
                } else {
                    for (ReagentPrintRecordDTO record : doc.getRecords()) {
                        recordTable.addCell(createCell(record.getOperateType(), tableBodyFont, Color.WHITE));
                        recordTable.addCell(createCell(record.getOperateTime(), tableBodyFont, Color.WHITE));
                        recordTable.addCell(createCell(record.getReagentNumber(), tableBodyFont, Color.WHITE));
                        recordTable.addCell(createCell(record.getReagentUnit(), tableBodyFont, Color.WHITE));
                        recordTable.addCell(createCell(record.getReagentPrice(), tableBodyFont, Color.WHITE));
                        recordTable.addCell(createCell(record.getDeptName(), tableBodyFont, Color.WHITE));
                        recordTable.addCell(createCell(record.getOperater(), tableBodyFont, Color.WHITE));
                        recordTable.addCell(createCell(record.getBatchNo(), tableBodyFont, Color.WHITE));
                        recordTable.addCell(createCell(record.getRemark(), tableBodyFont, Color.WHITE));
                        recordTable.addCell(createCell(record.getAuditUserName(), tableBodyFont, Color.WHITE));
                    }
                }

                document.add(recordTable);
            }

            document.close();
            return outputStream.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException("生成PDF失?。? + e.getMessage(), e);
        }
    }

    private static void addHeader(PdfPTable table, Font font, String... headers) {
        for (String header : headers) {
            PdfPCell cell = createCell(header, font, new Color(230, 230, 230));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            table.addCell(cell);
        }
    }

    private static PdfPCell createCell(String text, Font font, Color backgroundColor) {
        PdfPCell cell = new PdfPCell(new Phrase(text == null ? "--" : text, font));
        cell.setPadding(6f);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setBackgroundColor(backgroundColor);
        return cell;
    }
}

十二、核心 Service 實現(xiàn)

把查詢、組裝、渲染、附件保存串起來。

basemanage/platform/main/reagent/service/ReagentServiceImpl.java

1. 注入新增依賴

@Resource
private ReagentPrintAssembler reagentPrintAssembler;

@Resource
private BaseFileService baseFileService;

private static final String EXPORT_TABLE_NAME = "t_reagent_export";
private static final DateTimeFormatter EXPORT_TIME_FORMATTER =
        DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

2. 導(dǎo)出核心方法

@Override
public void exportPrintPdf(ReagentPrintRequest request, HttpServletResponse response) {
    if (request == null || PxListUtils.isEmpty(request.getIds())) {
        throw new RuntimeException("參數(shù)錯誤,試劑id不能為空!");
    }

    List<String> ids = request.getIds().stream()
            .filter(PxStringUtils::isNotEmpty)
            .distinct()
            .collect(Collectors.toList());

    if (PxListUtils.isEmpty(ids)) {
        throw new RuntimeException("參數(shù)錯誤,試劑id不能為空!");
    }

    List<ReagentBean> reagentBeans = getMapper().selectBatchIds(ids);
    if (PxListUtils.isEmpty(reagentBeans)) {
        throw new RuntimeException("未找到對應(yīng)的試劑信息!");
    }

    List<ReagentRecordBean> recordBeans = reagentRecordMapper.selectListByReagentIds(ids);
    Map<String, List<ReagentRecordBean>> recordMap = recordBeans.stream()
            .collect(Collectors.groupingBy(ReagentRecordBean::getReagentId));

    List<ReagentPrintDTO> printDocs = new ArrayList<>();
    for (String id : ids) {
        ReagentBean reagentBean = reagentBeans.stream()
                .filter(t -> id.equals(t.getId()))
                .findFirst()
                .orElse(null);
        if (reagentBean == null) {
            continue;
        }

        printDocs.add(reagentPrintAssembler.assemble(
                reagentBean,
                recordMap.getOrDefault(id, Collections.emptyList())
        ));
    }

    if (PxListUtils.isEmpty(printDocs)) {
        throw new RuntimeException("未找到可導(dǎo)出的試劑信息!");
    }

    byte[] pdfBytes = PdfRenderUtil.renderReagentPrintPdf(printDocs);
    String fileName = "試劑領(lǐng)用打印單_" + LocalDateTime.now().format(EXPORT_TIME_FORMATTER) + ".pdf";

    if (Boolean.TRUE.equals(request.getSaveAttachment())) {
        String batchId = PxBeanUtils.newStrId();

        BaseFileBean fileBean = new BaseFileBean();
        fileBean.setObjId(batchId);
        fileBean.setTableName(EXPORT_TABLE_NAME);
        fileBean.setFileType("pdf");
        fileBean.setOriginalName(fileName);
        fileBean.setRemark(String.join(",", ids));

        BaseFileBean savedFile = baseFileService.saveGeneratedFile(pdfBytes, fileBean);

        response.setHeader("X-Export-File-Id", savedFile.getId());
        response.setHeader("X-Export-Obj-Id", batchId);
    }

    writePdfResponse(response, pdfBytes, fileName);
}

3. 輸出 PDF 到瀏覽器

private void writePdfResponse(HttpServletResponse response, byte[] pdfBytes, String fileName) {
    try {
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition",
                "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
        response.setContentLength(pdfBytes.length);
        response.getOutputStream().write(pdfBytes);
        response.getOutputStream().flush();
    } catch (IOException e) {
        throw new RuntimeException("PDF下載失敗!");
    }
}

十三、批量導(dǎo)出時使用“導(dǎo)出批次號”保存附件

當(dāng)用戶勾選多個試劑時,導(dǎo)出的是個 PDF 文件,那這個文件應(yīng)該掛在哪個業(yè)務(wù)對象下?

錯誤做法:直接掛在某一個試劑 ID 下。

問題:

  • 這個 PDF 實際包含多條試劑
  • 只掛在一個試劑下面語義不準(zhǔn)確

更合理的做法

生成一個“導(dǎo)出批次號”作為objId。

String batchId = PxBeanUtils.newStrId();
fileBean.setObjId(batchId);
fileBean.setTableName("t_reagent_export");

這樣保存到附件表時,語義是:

  • 這是一份“試劑導(dǎo)出批次文件”
  • 不是某一條單獨試劑的從屬文件

這在批量導(dǎo)出場景下更清晰。

十四、擴展附件服務(wù):支持保存生成文件

項目原來的BaseFileService#upload只支持MultipartFile上傳,不適合保存程序動態(tài)生成的 PDF。

所以需要擴展一個新方法:

文件位置

basemanage/platform/main/basefile/service/BaseFileService.java

BaseFileBean saveGeneratedFile(byte[] fileBytes, BaseFileBean fileBean);

實現(xiàn)類

文件位置:basemanage/platform/main/basefile/service/BaseFileServiceImpl.java

@Override
public BaseFileBean saveGeneratedFile(byte[] fileBytes, BaseFileBean fileBean) {
    if (fileBytes == null || fileBytes.length == 0) {
        throw new RuntimeException("文件內(nèi)容不能為空!");
    }
    if (PxObjectUtils.isEmpty(fileBean)
            || PxObjectUtils.isEmpty(fileBean.getTableName())
            || PxObjectUtils.isEmpty(fileBean.getObjId())) {
        throw new RuntimeException("參數(shù)錯誤,【tableName,objId】不能為空!");
    }

    String originalName = fileBean.getOriginalName();
    if (PxObjectUtils.isEmpty(originalName)) {
        originalName = "generated-file.pdf";
        fileBean.setOriginalName(originalName);
    }

    String suffix = originalName.contains(".")
            ? originalName.substring(originalName.lastIndexOf("."))
            : ".pdf";

    fileBean.setSuffix(suffix);

    String uuidName = getUuid() + suffix;
    String filePath = System.getProperty("user.dir")
            + File.separator + "UPLOADFILE"
            + File.separator + fileBean.getTableName()
            + File.separator + getYearMonth()
            + File.separator + uuidName;

    fileBean.setFileName(uuidName);
    fileBean.setFilePath(filePath);

    File file = new File(filePath);
    if (!file.getParentFile().exists()) {
        boolean mkdirs = file.getParentFile().mkdirs();
        if (!mkdirs) {
            throw new RuntimeException("創(chuàng)建文件夾失??!");
        }
    }

    try (FileOutputStream fos = new FileOutputStream(file)) {
        fos.write(fileBytes);

        UserBean loginUser = PxLocalContextHelper.getLoginUser();
        fileBean.setFileSize(Math.round(file.length() / 1024.0 * 100.0) / 100.0);

        if (fileBean.getSort() == null) {
            fileBean.setSort(1);
        }

        if (loginUser != null) {
            fileBean.setCreatedById(loginUser.getId());
            fileBean.setCreatedByName(loginUser.getRealName());
        }

        fileBean.setCreateTime(LocalDateTime.now());
        fileBean.setId(PxBeanUtils.newStrId());
        getMapper().insert(fileBean);
        return fileBean;
    } catch (IOException e) {
        throw new RuntimeException("文件存儲失??!");
    }
}

十五、ApiPost 測試方式

請求地址

POST /control/reagent/exportPrintPdf

請求頭

Content-Type: application/json
Authorization: token

請求體

{
  "ids": ["試劑主表ID1", "試劑主表ID2"],
  "saveAttachment": true
}

預(yù)期結(jié)果

正常時:

  • 返回文件流
  • Content-Type: application/pdf
  • 瀏覽器或 ApiPost 可直接保存為 PDF

保存后的文件位置

如果保存附件成功,文件會落到本地目錄:

項目根目錄/UPLOADFILE/t_reagent_export/yyyyMM/

數(shù)據(jù)庫記錄會寫到:

t_base_file
src/main/java
├── com/px/basemanage/core/pdf
│   └── PdfRenderUtil.java
│
├── com/px/basemanage/platform/main/reagent/bean
│   ├── ReagentPrintRequest.java
│   ├── ReagentPrintDTO.java
│   └── ReagentPrintRecordDTO.java
│
├── com/px/basemanage/platform/main/reagent/controller
│   ├── ReagentController.java
│   └── ReagentControllerImpl.java
│
├── com/px/basemanage/platform/main/reagent/service
│   ├── ReagentService.java
│   ├── ReagentServiceImpl.java
│   └── ReagentPrintAssembler.java
│
├── com/px/basemanage/platform/main/reagent/dao
│   └── ReagentRecordMapper.java
│
└── com/px/basemanage/platform/main/basefile/service
    ├── BaseFileService.java
    └── BaseFileServiceImpl.java

以上就是SpringBoot將業(yè)務(wù)模塊數(shù)據(jù)導(dǎo)出為PDF的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot業(yè)務(wù)模塊數(shù)據(jù)導(dǎo)出為PDF的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

息烽县| 平利县| 边坝县| 灵丘县| 彭州市| 遵义县| 巴塘县| 子洲县| 渭源县| 清徐县| 改则县| 唐河县| 伊川县| 马鞍山市| 九江县| 兴安盟| 苍溪县| 年辖:市辖区| 师宗县| 女性| 资中县| 澎湖县| 武夷山市| 特克斯县| 绵阳市| 肃宁县| 泽州县| 扬中市| 分宜县| 上栗县| 绥宁县| 龙海市| 诏安县| 怀宁县| 广州市| 瑞金市| 嘉鱼县| 大悟县| 湘阴县| 江阴市| 本溪|