czt
2025-12-29 66e1e898f5020b5e02a99e361569637a72f8c2cf
优化公司、库区、仓库页面,通知单word导出提交
已修改12个文件
已添加6个文件
963 ■■■■■ 文件已修改
fzzy-igdss-core/pom.xml 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-core/src/main/java/com/fzzy/igds/constant/Constant.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-core/src/main/java/com/fzzy/igds/data/ExportWordParam.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-core/src/main/java/com/fzzy/igds/domain/PledgeContract.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-core/src/main/java/com/fzzy/igds/service/FileService.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-core/src/main/java/com/fzzy/igds/service/InoutNoticeService.java 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-core/src/main/java/com/fzzy/igds/utils/WordUtil.java 326 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-core/src/main/resources/lib/aspose-slides-19.3.jar 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-core/src/main/resources/lib/aspose-words-15.8.0-jdk16.jar 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-view/src/main/java/com/fzzy/igds/Company.view.xml 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-view/src/main/java/com/fzzy/igds/Depot.view.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-view/src/main/java/com/fzzy/igds/Dept.view.xml 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-view/src/main/java/com/fzzy/igds/InoutNoticeIn.view.xml 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-view/src/main/java/com/fzzy/igds/InoutNoticeOut.view.xml 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-view/src/main/java/com/fzzy/igds/PledgeContract.view.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-view/src/main/java/models/core.model.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/java/com/fzzy/common/ExportController.java 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/java/com/fzzy/common/manager/ExportManager.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-core/pom.xml
@@ -61,6 +61,49 @@
            <version>1.0.0-RELEASE</version>
        </dependency>
        <!-- word导出  æ–¹å¼ä¸€ï¼špoi-tl-->
        <!-- poi-tl是基于Apache POI的Word模板引擎。poi-tl依赖的是poi3.16版本 -->
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
            <version>1.7.3</version>
        </dependency>
        <!--  ä¸Šé¢éœ€è¦çš„依赖-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>
        <!--  -->
        <dependency>
            <groupId>com.aspose</groupId>
            <artifactId>aspose-words</artifactId>
            <version>15.8.0-jdk</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/resources/lib/aspose-words-15.8.0-jdk16.jar</systemPath>
        </dependency>
        <!--  -->
        <dependency>
            <groupId>aspose.slides</groupId>
            <artifactId>aspose-slides</artifactId>
            <version>19.3</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/resources/lib/aspose-slides-19.3.jar</systemPath>
        </dependency>
    </dependencies>
fzzy-igdss-core/src/main/java/com/fzzy/igds/constant/Constant.java
@@ -208,4 +208,9 @@
    public static final double FAULT_TEMP = -101;
    //-粮温补偿点-针对锥形仓补点使用
    public static final double ADD_TEMP = -102;
    /**
     * å¯¼å‡ºword业务类型
     */
    public static final String WORD_BIZ_TYPE_NOTICE = "NOTICE";
}
fzzy-igdss-core/src/main/java/com/fzzy/igds/data/ExportWordParam.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,80 @@
package com.fzzy.igds.data;
import lombok.Data;
import java.util.List;
import java.util.Map;
/**
 * @Description æ¡£æ¡ˆæŸ¥è¯¢å‚æ•°
 * @Author CZT
 * @Date 2025/12/29 16:26
 */
@Data
public class ExportWordParam {
    /**
     * åº“区编码
     */
    private String deptId;
    /**
     * ç¼–码
     */
    private String bizId;
    /**
     * å®žä½“名称
     */
    private String entityName;
    /**
     * æ•°æ®æº
     */
    private Map<String, Object> dataMap;
    /**
     * æ•°æ®æº-多条数据并且模板是多个一模一样的表单使用
     */
    private List<Map<String, Object>> dataList;
    /**
     * æ•°æ®æº-子表1集合名
     */
    private String listName1;
    /**
     * æ•°æ®æº-子表2集合名
     */
    private String listName2;
    /**
     * æ•°æ®æº-子表3集合名
     */
    private String listName3;
    /**
     * æ•°æ®æº-子表4集合名
     */
    private String listName4;
    /**
     * æ•°æ®æº-子表5集合名
     */
    private String listName5;
    /**
     * æ–‡æ¡£æ¨¡æ¿è·¯å¾„
     */
    private String templatePath;
    /**
     * æ–‡æ¡£æ¨¡æ¿åç§°
     */
    private String templateName;
    /**
     * æ–‡æ¡£ä¿å­˜è·¯å¾„
     */
    private String savePath;
}
fzzy-igdss-core/src/main/java/com/fzzy/igds/domain/PledgeContract.java
@@ -69,6 +69,10 @@
    @TableField("name")
    private String name;
    @Column(name = "depot_ids", columnDefinition = "varchar(200) COMMENT '质押仓库'")
    @TableField("depot_ids")
    private String depotIds;
    @Column(name = "status", columnDefinition = "varchar(2) COMMENT '质押状态'")
    @TableField("status")
    private String status = Constant.YN_N;
fzzy-igdss-core/src/main/java/com/fzzy/igds/service/FileService.java
@@ -252,4 +252,33 @@
        return path;
    }
    /**
     * èŽ·å–æ¨¡æ¿è·¯å¾„ï¼šæ‰€æœ‰æ¨¡æ¿ç»Ÿä¸€æ”¾åœ¨TEMPLATE/目录下
     * @return
     */
    public String getTemplateFilePath() {
        String basePath = FrameworkConfig.getProfile() + "TEMPLATE/";
        File file = new File(basePath);
        if (!file.exists()) {
            file.mkdirs();
        }
        return basePath;
    }
    /**
     * èŽ·å–word路径
     * @param deptId
     * @return
     */
    public String getWordPath(String deptId) {
        if(StringUtils.isBlank(deptId)){
            deptId = "0000";
        }
        String basePath = FrameworkConfig.getProfile() + deptId + "/WORD/";
        File file = new File(basePath);
        if (!file.exists()) {
            file.mkdirs();
        }
        return basePath;
    }
}
fzzy-igdss-core/src/main/java/com/fzzy/igds/service/InoutNoticeService.java
@@ -3,8 +3,11 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fzzy.igds.constant.AuditStatus;
import com.fzzy.igds.constant.Constant;
import com.fzzy.igds.data.ExportWordParam;
import com.fzzy.igds.data.NoticeDto;
import com.fzzy.igds.data.NoticeParam;
import com.fzzy.igds.domain.Depot;
import com.fzzy.igds.domain.Dept;
import com.fzzy.igds.mapper.InoutNoticeInMapper;
import com.fzzy.igds.mapper.InoutNoticeOutMapper;
import com.fzzy.igds.domain.InoutNoticeIn;
@@ -12,12 +15,15 @@
import com.fzzy.igds.utils.ContextUtil;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @Description å‡ºå…¥åº“通知单service层,包含入库通知单和出库通知单
@@ -32,6 +38,10 @@
    private InoutNoticeInMapper noticeInMapper;
    @Resource
    private InoutNoticeOutMapper noticeOutMapper;
    @Resource
    private DepotService depotService;
    @Resource
    private CoreDeptService coreDeptService;
    /*----------------------入库通知单信息-------------------------*/
    /**
@@ -381,4 +391,110 @@
        return null;
    }
    /**
     *
     * @param param
     * @return
     */
    public ExportWordParam handleInData(ExportWordParam param) {
        InoutNoticeIn notice = this.getNoticeInOne(param.getBizId());
        //转换为模板需要的map数据源
        Map<String, Object> map = new HashMap();
        map.put("serId", notice.getId());
        map.put("name", notice.getName());
        String type = "";
        if("10".equals(notice.getType())){
            type = "库区通知单";
        }
        if("20".equals(notice.getType())){
            type = "监管通知单";
        }
        map.put("type", type);
        map.put("customerName", notice.getCustomerName());
        String unitName = "";
        Dept dept = coreDeptService.getDeptById(notice.getUnitName());
        if(dept != null){
            unitName = dept.getKqmc();
        }
        map.put("unitName", unitName);
        Depot depot = depotService.getCacheDepot(notice.getCompanyId(), notice.getDepotId());
        String depotId = "";
        if(dept != null){
            depotId = depot.getName();
        }
        map.put("depotId", depotId);
        map.put("year", notice.getYear());
        map.put("targetNumber", notice.getTargetNumber());
        map.put("completeNumber", notice.getCompleteNumber());
        map.put("completeStatus", notice.getCompleteStatus());
        map.put("contract", notice.getContract());
        map.put("remark", notice.getRemark());
        map.put("createUser", notice.getCreateBy());
        map.put("createTime", DateFormatUtils.format(notice.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
        param.setDataMap(map);
        return param;
    }
    /**
     *
     * @param param
     * @return
     */
    public ExportWordParam handleOutData(ExportWordParam param) {
        InoutNoticeOut notice = this.getNoticeOutOne(param.getBizId());
        //转换为模板需要的map数据源
        Map<String, Object> map = new HashMap();
        map.put("serId", notice.getId());
        map.put("name", notice.getName());
        String type = "";
        if("10".equals(notice.getType())){
            type = "库区通知单";
        }
        if("20".equals(notice.getType())){
            type = "监管通知单";
        }
        map.put("type", type);
        map.put("customerName", notice.getCustomerName());
        String unitName = "";
        Dept dept = coreDeptService.getDeptById(notice.getUnitName());
        if(dept != null){
            unitName = dept.getKqmc();
        }
        map.put("unitName", unitName);
        Depot depot = depotService.getCacheDepot(notice.getCompanyId(), notice.getDepotId());
        String depotId = "";
        if(dept != null){
            depotId = depot.getName();
        }
        map.put("depotId", depotId);
        map.put("year", notice.getYear());
        map.put("targetNumber", notice.getTargetNumber());
        map.put("completeNumber", notice.getCompleteNumber());
        map.put("completeStatus", notice.getCompleteStatus());
        map.put("contract", notice.getContract());
        map.put("remark", notice.getRemark());
        map.put("createUser", notice.getCreateBy());
        map.put("createTime", DateFormatUtils.format(notice.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
        param.setDataMap(map);
        return param;
    }
}
fzzy-igdss-core/src/main/java/com/fzzy/igds/utils/WordUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,326 @@
package com.fzzy.igds.utils;
import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.deepoove.poi.policy.HackLoopTableRenderPolicy;
import com.fzzy.igds.data.ExportWordParam;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
import org.springframework.http.MediaType;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @Description æ–‡æ¡£å·¥å…·ç±»ï¼Œå°†æ•°æ®æºå¡«å……到模板并另存文件
 * @Author CZT
 * @Date 2025/4/21 16:14
 */
public class WordUtil {
    /**
     * è®¸å¯è¯å­—符串(可以放到resource下的xml文件中也可)
     */
    private static final String LICENSE = "<License>" +
            "<Data>" +
            "<Products><Product>Aspose.Total for Java</Product><Product>Aspose.Words for Java</Product></Products>" +
            "<EditionType>Enterprise</EditionType>" +
            "<SubscriptionExpiry>20991231</SubscriptionExpiry>" +
            "<LicenseExpiry>20991231</LicenseExpiry>" +
            "<SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>" +
            "</Data>" +
            "<Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>" +
            "</License>";
    /**
     * å°†æ•°æ®æºå¡«å……到模板中并另存:主表+子表(可只有列表)
     *
     * @param param      æ•°æ®æº
     * @throws IOException
     */
    public static void exportWord(ExportWordParam param) throws Exception {
        //渲染模板
        HackLoopTableRenderPolicy policy = new HackLoopTableRenderPolicy();
        Configure config = null;
        ConfigureBuilder configureBuilder = Configure.newBuilder();
        if(StringUtils.isNotEmpty(param.getListName1())){
            configureBuilder.bind(param.getListName1(), policy);
        }
        if(StringUtils.isNotEmpty(param.getListName2())){
            configureBuilder.bind(param.getListName2(), policy);
        }
        if(StringUtils.isNotEmpty(param.getListName3())){
            configureBuilder.bind(param.getListName3(), policy);
        }
        if(StringUtils.isNotEmpty(param.getListName4())){
            configureBuilder.bind(param.getListName4(), policy);
        }
        if(StringUtils.isNotEmpty(param.getListName5())){
            configureBuilder.bind(param.getListName5(), policy);
        }
        config = configureBuilder.build();
        XWPFTemplate template = XWPFTemplate.compile(param.getTemplatePath() + param.getTemplateName(), config).render(param.getDataMap());
        //模板文件保存
        FileOutputStream fos = new FileOutputStream(param.getSavePath() +  param.getTemplateName());
        template.write(fos);
    }
    /**
     * å°†æ•°æ®æºå¡«å……到模板中并另存:主表+子表(可只有列表)
     *
     * @param param      æ•°æ®æº
     * @throws IOException
     */
    public static void exportMoreWord(ExportWordParam param) throws Exception {
        Integer index = 900;
        List<String> wordList = new ArrayList<>();
        for (Map<String, Object> dataMap : param.getDataList()) {
            //渲染模板
            HackLoopTableRenderPolicy policy = new HackLoopTableRenderPolicy();
            Configure config = null;
            ConfigureBuilder configureBuilder = Configure.newBuilder();
            if(StringUtils.isNotEmpty(param.getListName1())){
                configureBuilder.bind(param.getListName1(), policy);
            }
            if(StringUtils.isNotEmpty(param.getListName2())){
                configureBuilder.bind(param.getListName2(), policy);
            }
            if(StringUtils.isNotEmpty(param.getListName3())){
                configureBuilder.bind(param.getListName3(), policy);
            }
            if(StringUtils.isNotEmpty(param.getListName4())){
                configureBuilder.bind(param.getListName4(), policy);
            }
            if(StringUtils.isNotEmpty(param.getListName5())){
                configureBuilder.bind(param.getListName5(), policy);
            }
            config = configureBuilder.build();
            XWPFTemplate template = XWPFTemplate.compile(param.getTemplatePath() + param.getTemplateName(), config).render(dataMap);
            wordList.add(param.getSavePath() + index + "-" + param.getTemplateName());
            //模板文件保存
            FileOutputStream fos = new FileOutputStream(param.getSavePath() + index + "-" + param.getTemplateName());
            template.write(fos);
            index ++;
        }
        //多个word合并
        mergeWord(wordList, param.getSavePath(), param.getTemplateName());
    }
    /**
     * ä¸‹è½½æ–‡æ¡£
     *
     * @param filePath æ–‡æ¡£è·¯å¾„
     * @param fileName æ–‡æ¡£åç§°
     * @param response
     * @throws Exception
     */
    public static void download(String filePath, String fileName, HttpServletResponse response) throws Exception {
        //下载
        if (!FileUtils.checkAllowDownload(fileName)) {
            throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
        }
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        FileUtils.setAttachmentResponseHeader(response, fileName);
        FileUtils.writeBytes(filePath + fileName, response.getOutputStream());
    }
    /**
     * è®¾ç½® license åŽ»é™¤æ°´å°
     */
    private static void setLicense() {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(LICENSE.getBytes());
        License license = new License();
        try {
            license.setLicense(byteArrayInputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * word è½¬ pdf ç”Ÿæˆè‡³æŒ‡å®šè·¯å¾„,pdf为空则上传至word同级目录
     *
     * @param wordPath word文件路径
     * @param pdfPath  pdf文件路径
     */
    public static void wordConvertPdfFile(String wordPath, String pdfPath) {
        FileOutputStream fileOutputStream = null;
        try {
            setLicense();
            File file = new File(pdfPath);
            fileOutputStream = new FileOutputStream(file);
            Document doc = new Document(wordPath);
            doc.save(fileOutputStream, SaveFormat.PDF);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                assert fileOutputStream != null;
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * èŽ·å– ç”Ÿæˆçš„ pdf æ–‡ä»¶è·¯å¾„,默认与源文件同一目录
     *
     * @param inputFilePath word文件
     * @return ç”Ÿæˆçš„ pdf æ–‡ä»¶
     */
    public static String getPdfName(String inputFilePath) {
        return inputFilePath.replaceAll("."+ getPostfix(inputFilePath), ".pdf");
    }
    public static String getPostfix(String inputFilePath) {
        return inputFilePath.substring(inputFilePath.lastIndexOf(".") + 1);
    }
    /*-------------多个word合并到成1个word文档----------*/
    public static void mergeWord(List<String> wordList, String mergeWordPath, String mergeWordName) {
        List<File> srcfile = new ArrayList<>();
        File file = null;
        for (String word : wordList) {
            file = new File(word);
            srcfile.add(file);
        }
        try {
            ArrayList<XWPFDocument> documentList = new ArrayList<>();
            for (int i = 0; i < srcfile.size(); i++) {
                FileInputStream in = new FileInputStream(srcfile.get(i).getPath());
                OPCPackage open = OPCPackage.open(in);
                XWPFDocument document = new XWPFDocument(open);
                documentList.add(document);
            }
            XWPFDocument doc = documentList.get(0);
            if (CollectionUtils.isEmpty(documentList)) {
                throw  new RuntimeException("待合并的word文档list为空");
            }
            int size = documentList.size();
            if (size > 1) {
                for (int i = 1; i < size; i++) {
                    // ä»Žç¬¬äºŒä¸ªword开始合并
                    XWPFDocument nextPageDoc = documentList.get(i);
                    // æœ€åŽä¸€é¡µä¸éœ€è¦è®¾ç½®åˆ†é¡µç¬¦,设置分页符后容易换页,可以去掉
                    if (i != (size-1)) {
                        nextPageDoc.createParagraph().setPageBreak(true);
                    }
                    appendBody(doc, nextPageDoc);
                }
            }
            new File(mergeWordPath + mergeWordName).delete();
            OutputStream dest = new FileOutputStream(mergeWordPath + mergeWordName);
            doc.write(dest);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void aqscMergeDoc(String outPutPath, String mergeWord) {
        List<File> srcfile = new ArrayList<>();
        File file1 = new File(outPutPath);
        File file2 = new File(mergeWord);
        srcfile.add(file1);
        srcfile.add(file2);
        try {
            ArrayList<XWPFDocument> documentList = new ArrayList<>();
            for (int i = 0; i < srcfile.size(); i++) {
                FileInputStream in = new FileInputStream(srcfile.get(i).getPath());
                OPCPackage open = OPCPackage.open(in);
                XWPFDocument document = new XWPFDocument(open);
                documentList.add(document);
            }
            XWPFDocument doc = documentList.get(0);
            if (CollectionUtils.isEmpty(documentList)) {
                throw  new RuntimeException("待合并的word文档list为空");
            }
            int size = documentList.size();
            if (size > 1) {
                doc.createParagraph().setPageBreak(true);
                for (int i = 1; i < size; i++) {
                    // ä»Žç¬¬äºŒä¸ªword开始合并
                    XWPFDocument nextPageDoc = documentList.get(i);
                    // æœ€åŽä¸€é¡µä¸éœ€è¦è®¾ç½®åˆ†é¡µç¬¦
                    if (i != (size-1)) {
                        nextPageDoc.createParagraph().setPageBreak(true);
                    }
                    appendBody(doc, nextPageDoc);
                }
            }
            new File(outPutPath).delete();
            OutputStream dest = new FileOutputStream(outPutPath);
            doc.write(dest);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void appendBody(XWPFDocument src, XWPFDocument append) throws Exception {
        CTBody src1Body = src.getDocument().getBody();
        CTBody src2Body = append.getDocument().getBody();
        List<XWPFPictureData> allPictures = append.getAllPictures();
        // è®°å½•图片合并前及合并后的ID
        Map<String, String> map = new HashMap<>();
        for (XWPFPictureData picture : allPictures) {
            String before = append.getRelationId(picture);
            // å°†åŽŸæ–‡æ¡£ä¸­çš„å›¾ç‰‡åŠ å…¥åˆ°ç›®æ ‡æ–‡æ¡£ä¸­
            String after = src.addPictureData(picture.getData(), org.apache.poi.xwpf.usermodel.Document.PICTURE_TYPE_PNG);
            map.put(before, after);
        }
        appendBody(src1Body, src2Body, map);
    }
    private static void appendBody(CTBody src, CTBody append, Map<String, String> map) throws Exception {
        XmlOptions optionsOuter = new XmlOptions();
        optionsOuter.setSaveOuter();
        String appendString = append.xmlText(optionsOuter);
        String rgex = "<[\\s]*?w:sectPr[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?w:sectPr[\\s]*?>";
        appendString = appendString.replaceAll(rgex, "");
//        String srcString = src.xmlText();
        // åŽ»é™¤åˆ†é¡µç¬¦
        String srcString = src.xmlText().replaceAll( "<w:p><w:r><w:br w:type=\"page\"/></w:r></w:p>", "" ).replaceAll( "<w:r><w:br w:type=\"page\"/></w:r>", "" );
        String prefix = srcString.substring(0, srcString.indexOf(">"));
        String mainPart = srcString.substring(srcString.indexOf(">"), srcString.lastIndexOf("<"));
        String sufix = srcString.substring(srcString.lastIndexOf("<"));
        String addPart = appendString.substring(appendString.indexOf(">"), appendString.lastIndexOf("<"));
        if (map != null && !map.isEmpty()) {
            // å¯¹xml字符串中图片ID进行替换
            for (Map.Entry<String, String> set : map.entrySet()) {
                addPart = addPart.replace(set.getKey(), set.getValue());
            }
        }
        // å°†ä¸¤ä¸ªæ–‡æ¡£çš„xml内容进行拼接
        CTBody makeBody = CTBody.Factory.parse(prefix + mainPart + addPart + sufix);
        src.set(makeBody);
    }
}
fzzy-igdss-core/src/main/resources/lib/aspose-slides-19.3.jar
Binary files differ
fzzy-igdss-core/src/main/resources/lib/aspose-words-15.8.0-jdk16.jar
Binary files differ
fzzy-igdss-view/src/main/java/com/fzzy/igds/Company.view.xml
@@ -236,6 +236,12 @@
    if(!txt) return true;&#xD;
    var htm = &quot;&lt;a href='javascript:;' onClick='showDlg()' >&quot;+txt+&quot;&lt;/a>&quot;;&#xD;
    arg.dom.innerHTML = htm;&#xD;
}
renderName = function(arg){&#xD;
    var txt = arg.data.getText(&quot;dwmc&quot;);&#xD;
    if(!txt) return true;&#xD;
    var htm = &quot;&lt;a href='javascript:;' onClick='showDlg()' >&quot;+txt+&quot;&lt;/a>&quot;;&#xD;
    arg.dom.innerHTML = htm;&#xD;
}</ClientEvent>
    <Property name="packages">font-awesome,css-common</Property>
    <DataSet id="dsMain">
@@ -281,6 +287,7 @@
        </DataColumn>
        <DataColumn name="dwmc">
          <Property name="property">dwmc</Property>
          <ClientEvent name="onRenderCell">renderName(arg);</ClientEvent>
        </DataColumn>
        <DataColumn name="dwdm">
          <Property name="property">dwdm</Property>
@@ -323,7 +330,7 @@
          <Property name="width">160</Property>
        </DataColumn>
        <DataColumn>
          <ClientEvent name="onRenderCell">arg.dom.innerHTML = &quot;&lt;a href='javascript:;' onClick='detail()' class='a-btn1'>查看详情&lt;/a>&quot;;</ClientEvent>
          <ClientEvent name="onRenderCell">arg.dom.innerHTML = &quot;&lt;a href='javascript:;' onClick='detail()' class='a-btn1'>查看库区&lt;/a>&quot;;</ClientEvent>
          <Property name="width">160</Property>
          <Property name="caption">操作</Property>
          <Property name="align">center</Property>
fzzy-igdss-view/src/main/java/com/fzzy/igds/Depot.view.xml
@@ -44,6 +44,12 @@
    arg.dom.innerHTML = htm;&#xD;
}&#xD;
&#xD;
renderName = function(arg){&#xD;
    var txt = arg.data.getText(&quot;name&quot;);&#xD;
    if(!txt) return true;&#xD;
    var htm = &quot;&lt;a href='javascript:;' onClick='showDlg()' >&quot;+txt+&quot;&lt;/a>&quot;;&#xD;
    arg.dom.innerHTML = htm;&#xD;
}
</ClientEvent>
    <Property name="packages">font-awesome,css-common</Property>
    <DataSet id="dataSetdepot">
@@ -127,6 +133,7 @@
          <Property name="width">120</Property>
        </DataColumn>
        <DataColumn name="name">
          <ClientEvent name="onRenderCell">renderName(arg);</ClientEvent>
          <Property name="property">name</Property>
          <Property name="align">center</Property>
          <Property name="width">120</Property>
fzzy-igdss-view/src/main/java/com/fzzy/igds/Dept.view.xml
@@ -182,6 +182,12 @@
    if(!txt) return true;&#xD;
    var htm = &quot;&lt;a href='javascript:;' onClick='showDlg()' >&quot;+txt+&quot;&lt;/a>&quot;;&#xD;
    arg.dom.innerHTML = htm;&#xD;
}
renderName = function(arg){&#xD;
    var txt = arg.data.getText(&quot;kqmc&quot;);&#xD;
    if(!txt) return true;&#xD;
    var htm = &quot;&lt;a href='javascript:;' onClick='showDlg()' >&quot;+txt+&quot;&lt;/a>&quot;;&#xD;
    arg.dom.innerHTML = htm;&#xD;
}</ClientEvent>
    <Property name="packages">font-awesome,css-common</Property>
    <DataSet id="dsMain">
@@ -227,6 +233,7 @@
          <Property name="width">160</Property>
        </DataColumn>
        <DataColumn name="kqmc">
          <ClientEvent name="onRenderCell">renderName(arg);</ClientEvent>
          <Property name="property">kqmc</Property>
          <Property name="align">left</Property>
        </DataColumn>
@@ -259,7 +266,7 @@
          <Property name="width">160</Property>
        </DataColumn>
        <DataColumn>
          <ClientEvent name="onRenderCell">arg.dom.innerHTML = &quot;&lt;a href='javascript:;' onClick='detail()' class='a-btn1'>查看详情&lt;/a>&quot;;</ClientEvent>
          <ClientEvent name="onRenderCell">arg.dom.innerHTML = &quot;&lt;a href='javascript:;' onClick='detail()' class='a-btn1'>查看仓库&lt;/a>&quot;;</ClientEvent>
          <Property name="width">160</Property>
          <Property name="caption">操作</Property>
          <Property name="align">center</Property>
fzzy-igdss-view/src/main/java/com/fzzy/igds/InoutNoticeIn.view.xml
@@ -16,6 +16,11 @@
      <PropertyDef name="deptId">
        <Property></Property>
        <Property name="label">所属分库</Property>
        <Property name="mapping">
          <Property name="keyProperty">id</Property>
          <Property name="mapValues">${dorado.getDataProvider(&quot;deptPR#getAllData&quot;).getResult()}</Property>
          <Property name="valueProperty">kqmc</Property>
        </Property>
      </PropertyDef>
      <PropertyDef name="name">
        <Property></Property>
@@ -264,7 +269,7 @@
            select.remove();&#xD;
            });&#xD;
            }else{&#xD;
            $notify(&quot;请选择需要删除的仓库……&quot;);&#xD;
            $notify(&quot;请选择需要删除的数据……&quot;);&#xD;
            }</ClientEvent>
          <Property name="caption">删除</Property>
          <Property name="exClassName">btn3</Property>
@@ -285,8 +290,23 @@
          <Property name="caption">实时核算</Property>
          <Property name="exClassName">btn4</Property>
          <Property name="iconClass">fa fa-refresh</Property>
          <Property name="width">100</Property>
          <Property name="width">120</Property>
          <Property name="tip">完成量默认统计到昨天,查看实时完成量请点击“实时核算”按钮</Property>
        </ToolBarButton>
        <ToolBarButton layoutConstraint="left">
          <ClientEvent name="onClick">&#xD;
var select = view.get(&quot;#dataGridMain&quot;).get(&quot;selection&quot;);&#xD;
if(select){&#xD;
    var bizId = select.get(&quot;id&quot;);&#xD;
    var url = &quot;/export/download-word?bizId=&quot;+bizId + &quot;&amp;entityName=InoutNoticeIn&quot;;&#xD;
    window.open(url);&#xD;
}else{&#xD;
    $notify(&quot;请选择需要导出的通知单……&quot;);&#xD;
}</ClientEvent>
          <Property name="caption">导出Word</Property>
          <Property name="exClassName">btn2</Property>
          <Property name="width">120</Property>
          <Property name="iconClass">fa fa-print</Property>
        </ToolBarButton>
      </ToolBar>
      <DataGrid id="dataGridMain" layoutConstraint="padding:8">
@@ -307,8 +327,7 @@
        </DataColumn>
        <DataColumn>
          <Property name="property">deptId</Property>
          <Property name="align">center</Property>
          <Property name="width">150</Property>
          <Property name="align">left</Property>
          <Property name="name">deptId</Property>
        </DataColumn>
        <DataColumn name="name">
@@ -323,18 +342,18 @@
        <DataColumn name="depotId">
          <Property name="property">depotId</Property>
          <Property name="align">center</Property>
          <Property name="width">150</Property>
          <Property name="width">120</Property>
        </DataColumn>
        <DataColumn name="foodVariety">
          <Property name="property">foodVariety</Property>
          <Property name="align">center</Property>
          <Property name="width">150</Property>
          <Property name="width">120</Property>
        </DataColumn>
        <DataColumn>
          <Property name="property">targetNumber</Property>
          <Property name="name">targetNumber</Property>
          <Property name="align">center</Property>
          <Property name="width">200</Property>
          <Property name="width">120</Property>
        </DataColumn>
        <DataColumn>
          <Property name="property">completeStatus</Property>
@@ -343,21 +362,15 @@
          <Property name="width">100</Property>
        </DataColumn>
        <DataColumn>
          <Property name="property">createTime</Property>
          <Property name="align">center</Property>
          <Property name="name">createTime</Property>
          <Property name="width">160</Property>
        </DataColumn>
        <DataColumn>
          <Property name="property">updateBy</Property>
          <Property name="align">center</Property>
          <Property name="name">updateBy</Property>
          <Property name="width">120</Property>
        </DataColumn>
        <DataColumn>
          <Property name="property">updateTime</Property>
          <Property name="property">createTime</Property>
          <Property name="align">center</Property>
          <Property name="name">updateTime</Property>
          <Property name="name">createTime</Property>
          <Property name="width">160</Property>
        </DataColumn>
      </DataGrid>
fzzy-igdss-view/src/main/java/com/fzzy/igds/InoutNoticeOut.view.xml
@@ -16,6 +16,11 @@
      <PropertyDef name="deptId">
        <Property></Property>
        <Property name="label">所属分库</Property>
        <Property name="mapping">
          <Property name="keyProperty">id</Property>
          <Property name="mapValues">${dorado.getDataProvider(&quot;deptPR#getAllData&quot;).getResult()}</Property>
          <Property name="valueProperty">kqmc</Property>
        </Property>
      </PropertyDef>
      <PropertyDef name="name">
        <Property></Property>
@@ -306,6 +311,21 @@
          <Property name="width">100</Property>
          <Property name="tip">完成量默认统计到昨天,查看实时完成量请点击“实时核算”按钮</Property>
        </ToolBarButton>
        <ToolBarButton layoutConstraint="left">
          <ClientEvent name="onClick">&#xD;
            var select = view.get(&quot;#dataGridMain&quot;).get(&quot;selection&quot;);&#xD;
            if(select){&#xD;
            var bizId = select.get(&quot;id&quot;);&#xD;
            var url = &quot;/export/download-word?bizId=&quot;+bizId + &quot;&amp;entityName=InoutNoticeOut&quot;;&#xD;
            window.open(url);&#xD;
            }else{&#xD;
            $notify(&quot;请选择需要导出的通知单……&quot;);&#xD;
            }</ClientEvent>
          <Property name="caption">导出Word</Property>
          <Property name="exClassName">btn2</Property>
          <Property name="width">120</Property>
          <Property name="iconClass">fa fa-print</Property>
        </ToolBarButton>
      </ToolBar>
      <DataGrid id="dataGridMain" layoutConstraint="padding:8">
        <ClientEvent name="onDataRowDoubleClick">view.get(&quot;#dataGridMain&quot;).set(&quot;selection&quot;,arg.data);</ClientEvent>
@@ -323,6 +343,11 @@
          <Property name="width">200</Property>
          <Property name="align">center</Property>
        </DataColumn>
        <DataColumn>
          <Property name="property">deptId</Property>
          <Property name="align">left</Property>
          <Property name="name">deptId</Property>
        </DataColumn>
        <DataColumn name="name">
          <Property name="property">name</Property>
          <Property name="align">center</Property>
@@ -335,18 +360,18 @@
        <DataColumn name="depotId">
          <Property name="property">depotId</Property>
          <Property name="align">center</Property>
          <Property name="width">150</Property>
          <Property name="width">120</Property>
        </DataColumn>
        <DataColumn name="foodVariety">
          <Property name="property">foodVariety</Property>
          <Property name="align">center</Property>
          <Property name="width">150</Property>
          <Property name="width">120</Property>
        </DataColumn>
        <DataColumn>
          <Property name="property">targetNumber</Property>
          <Property name="name">targetNumber</Property>
          <Property name="align">center</Property>
          <Property name="width">200</Property>
          <Property name="width">120</Property>
        </DataColumn>
        <DataColumn>
          <Property name="property">completeStatus</Property>
@@ -355,21 +380,15 @@
          <Property name="width">100</Property>
        </DataColumn>
        <DataColumn>
          <Property name="property">createTime</Property>
          <Property name="align">center</Property>
          <Property name="name">createTime</Property>
          <Property name="width">200</Property>
        </DataColumn>
        <DataColumn>
          <Property name="property">updateBy</Property>
          <Property name="align">center</Property>
          <Property name="name">updateBy</Property>
          <Property name="width">120</Property>
        </DataColumn>
        <DataColumn>
          <Property name="property">updateTime</Property>
          <Property name="property">createTime</Property>
          <Property name="align">center</Property>
          <Property name="name">updateTime</Property>
          <Property name="name">createTime</Property>
          <Property name="width">160</Property>
        </DataColumn>
      </DataGrid>
fzzy-igdss-view/src/main/java/com/fzzy/igds/PledgeContract.view.xml
@@ -254,6 +254,11 @@
              <Property name="property">repaidAmount</Property>
              <Editor/>
            </AutoFormElement>
            <AutoFormElement>
              <Property name="name">depotIds</Property>
              <Property name="property">depotIds</Property>
              <Editor/>
            </AutoFormElement>
            <AutoFormElement layoutConstraint="colSpan:3">
              <Property name="name">remark</Property>
              <Property name="property">remark</Property>
fzzy-igdss-view/src/main/java/models/core.model.xml
@@ -1073,6 +1073,15 @@
        <Property name="minLength">1</Property>
      </Validator>
    </PropertyDef>
    <PropertyDef name="depotIds">
      <Property></Property>
      <Property name="label">质押仓库</Property>
      <Property name="mapping">
        <Property name="mapValues">${dorado.getDataProvider(&quot;depotPR#getAllCache&quot;).getResult()}</Property>
        <Property name="keyProperty">id</Property>
        <Property name="valueProperty">name</Property>
      </Property>
    </PropertyDef>
    <PropertyDef name="pledgeBank">
      <Property></Property>
      <Property name="label">所属银行</Property>
fzzy-igdss-web/src/main/java/com/fzzy/common/ExportController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,143 @@
package com.fzzy.common;
import com.fzzy.common.manager.ExportManager;
import com.fzzy.igds.ReportInDetailPR;
import com.fzzy.igds.ReportOutDetailPR;
import com.fzzy.igds.SuperInventoryReportPR;
import com.fzzy.igds.data.ExportWordParam;
import com.fzzy.igds.data.InoutParam;
import com.fzzy.igds.data.SuperInventoryReportData;
import com.fzzy.igds.data.SuperInventoryReportParam;
import com.fzzy.igds.domain.InoutRecord;
import com.fzzy.igds.service.SysDeptService;
import com.fzzy.igds.utils.ContextUtil;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
 * @Description  æ•°æ®å¯¼å‡ºå…¥å£
 * @Author CZT
 * @Date 2025/12/29 10:32
 */
@Slf4j
@Controller
@RequestMapping("export")
public class ExportController {
    @Resource
    private ExportManager exportManager;
    @Resource
    private SysDeptService sysDeptService;
    @Resource
    private ReportInDetailPR reportInDetailPR;
    @Resource
    private ReportOutDetailPR reportOutDetailPR;
    @Resource
    private SuperInventoryReportPR superInventoryReportPR;
    /**
     * å¯¼å‡ºword并下载
     *
     * @param response
     * @param bizId
     * @param entityName
     */
    @RequestMapping("/download-word")
    public void downloadWord(HttpServletResponse response,
                             @RequestParam(value = "bizId", required = true) String bizId,
                             @RequestParam(value = "entityName", required = true) String entityName) {
        ExportWordParam param = new ExportWordParam();
        param.setBizId(bizId);
        param.setEntityName(entityName);
        exportManager.renderWordDownload(param, response);
    }
    /**
     * PDF在线预览
     *
     * @param response
     * @param bizId
     * @param entityName
     */
    @RequestMapping("/preview-pdf")
    public void previewPdf(HttpServletResponse response,
                           @RequestParam(value = "bizId", required = true) String bizId,
                           @RequestParam(value = "entityName", required = true) String entityName) {
        //TODO å¾…实现
        ExportWordParam param = new ExportWordParam();
        param.setBizId(bizId);
        param.setEntityName(entityName);
    }
    /**
     * å‡ºå…¥åº“报表导出
     * @return
     */
    @RequestMapping("/inout-excel")
    @ResponseBody
    public AjaxResult inOutExcel(InoutParam param) {
        //设置标题
        String sheetName = "报表数据";
        //查询数据
        List<InoutRecord> list = new ArrayList<>();
        if (StringUtils.isNotEmpty(param.getType()) && "IN".equals(param.getType())) {
            sheetName = "入库报表数据";
            list = reportInDetailPR.listRecord(param);
        }
        if (StringUtils.isNotEmpty(param.getType()) && "OUT".equals(param.getType())) {
            sheetName = "出库报表数据";
            list = reportOutDetailPR.listRecord(param);
        }
        //获取分库编码对应的分库名称
        String deptName = "";
        SysDept subDept = sysDeptService.getCacheDept(null, ContextUtil.subDeptId(null));
        if (null != subDept) {
            deptName = subDept.getDeptName();
        }
        //导出
        ExcelUtil<InoutRecord> util = new ExcelUtil<InoutRecord>(InoutRecord.class);
        return util.exportExcel(list, sheetName, deptName);
    }
    /**
     * åº“存报表导出
     * @return
     */
    @RequestMapping("/storage-excel")
    @ResponseBody
    public AjaxResult storageExcel(SuperInventoryReportParam param) {
        //设置标题
        String sheetName = "库存报表数据";
        //查询数据
        List<SuperInventoryReportData> list = superInventoryReportPR.getReportData(param);
        //获取分库编码对应的分库名称
        String deptName = "";
        SysDept subDept = sysDeptService.getCacheDept(null, ContextUtil.subDeptId(null));
        if (null != subDept) {
            deptName = subDept.getDeptName();
        }
        //导出
        ExcelUtil<SuperInventoryReportData> util = new ExcelUtil<SuperInventoryReportData>(SuperInventoryReportData.class);
        return util.exportExcel(list, sheetName, deptName);
    }
}
fzzy-igdss-web/src/main/java/com/fzzy/common/manager/ExportManager.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,94 @@
package com.fzzy.common.manager;
import com.fzzy.igds.data.ExportWordParam;
import com.fzzy.igds.service.FileService;
import com.fzzy.igds.service.InoutNoticeService;
import com.fzzy.igds.utils.WordUtil;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
/**
 * @Description å¯¼å‡ºé¢„览下载业务处理
 * @Author CZT
 * @Date 2025/12/29 10:56
 */
@Slf4j
@Component
public class ExportManager {
    @Resource
    private FileService fileService;
    @Resource
    private InoutNoticeService noticeService;
    /**
     * æ¸²æŸ“模板保存并下载
     * @param param
     * @param response
     */
    public void renderWordDownload(ExportWordParam param, HttpServletResponse response) {
        try {
            if(null == param || StringUtils.isBlank(param.getEntityName())){
                log.error("业务类型为空,不执行导出!");
                return;
            }
            String templateName = null;
            //数据封装渲染
            if("InoutNoticeIn".equals(param.getEntityName())){
                templateName = "入库通知单.docx";
            }
            if("InoutNoticeOut".equals(param.getEntityName())){
                templateName = "出库通知单.docx";
            }
            if(StringUtils.isBlank(templateName)){
                log.error("模板名称为空,不执行导出!");
                return;
            }
            //获取模板路径
            String templatePath = fileService.getTemplateFilePath();
            File file = new File(templatePath + templateName);
            if (!file.exists()) {
                log.error("模板文件不存在,不执行导出!");
                return;
            }
            //获取文件保存路径,以库区分开
            String savePath = fileService.getWordPath(null);
            param.setTemplatePath(templatePath);
            param.setTemplateName(templateName);
            param.setSavePath(savePath);
            //数据封装渲染
            if("InoutNoticeIn".equals(param.getEntityName())){
                templateName = "入库通知单.docx";
                param = noticeService.handleInData(param);
            }
            if("InoutNoticeOut".equals(param.getEntityName())){
                templateName = "出库通知单.docx";
                param = noticeService.handleOutData(param);
            }
            //保存
            if (null != param.getDataList() && param.getDataList().size() > 1) {
                WordUtil.exportMoreWord(param);
            }else {
                WordUtil.exportWord(param);
            }
            // ä¸‹è½½ç”Ÿæˆçš„Word文档
            WordUtil.download(savePath, templateName, response);
        } catch (Exception e) {
            log.error("下载文件失败", e);
        }
    }
}