easyExcel 导入、导出Excel 封装公共的方法

news2024/11/18 6:43:27

文档包含三部分功能

1、easyExcel 公共导出list<对象>方法,可以自定义excel中第一行和样式
2、easyExcel 导入逻辑,结合spring Validator 验证导入数据是否符合规范
3、easyExcel 自定义导出 list<map> 、 list<对象> (可优化),可把sql.date,sql.time在excel转换正常显示

1、easyExcel 公共导出方法

1)依赖:

<!-- hutool -->
<!-- 阿里开源的excel处理包 -->
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>easyexcel</artifactId>
	<version>3.3.3</version>
</dependency>
<!-- poi -->
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi</artifactId>
	<version>5.0.0</version>
</dependency>
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>5.0.0</version>
</dependency>

 2)封装的公共导出方法:

# 其中 templateBool 代表第一行是否为标题行
# 其中 firstRowContent 代码第一行写入的内容
FileUtil.exportExcel(response, "导出应用表列表", "sheet1", App.class, appList, templateBool,firstRowContent);

其中 App.class 实体类属性添加 @ExcelIgnore 忽略导出,@ExcelProperty("*excel列明") 指出导出列表

@ExcelIgnore
@ExcelProperty("*excel列明")

导出代码参考 

easyExcel自定义导入头实现icon-default.png?t=N7T8https://www.cnblogs.com/Dog1363786601/p/17352096.html

3)实现easyExcel 导入导出依赖公共文件方法

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;

import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.util.IOUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 项目名称:base
 *
 * <p>功能: 功能描述。</p>
 *
 * @author:yht
 * @version:V1.0 2023/5/30
 */
@Slf4j
public class FileUtil {
    

    /**
     * 设置导出为excel 的 Response 中的描述
     *
     * @param response    响应结果对象
     * @param rawFileName 文件名
     */
    public static void setExcelResponse(HttpServletResponse response, String rawFileName) {
        //设置响应格式
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8"); // 设置字符编码
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = Base64.encode(rawFileName, Charset.defaultCharset());
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
    }

    /**
     * MultipartFile对象转成File对象
     *
     * @param multipartFile
     * @return
     */
    public static File transferToFile(MultipartFile multipartFile) {
//        选择用缓冲区来实现这个转换即使用java 创建的临时文件 使用 MultipartFile.transferto()方法 。
        File file = null;
        try {
            String originalFilename = multipartFile.getOriginalFilename();
            String[] filename = originalFilename.split("\\.");
            file = File.createTempFile(filename[0], filename[1] + ".");
            multipartFile.transferTo(file);
            file.deleteOnExit();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    /**
     * 断面数据导出Excel
     * <a href="https://www.cnblogs.com/Dog1363786601/p/17352096.html">EasyExcelSheetWriteHandler 参考:包含map导出样例</a>
     *
     * @param response:response
     * @param fileName:文件名
     * @param sheetName:sheet              页签名称
     * @param targetClass:目标对象Class
     * @param dateList:对象数据
     * @param firstRowDocBool:第一行是不是填写文档说明
     * @param firstRowContent:第一行的内容
     */
    public static void exportExcel(HttpServletResponse response, String fileName, String sheetName,
                                   Class<?> targetClass, List<?> dateList, Boolean firstRowDocBool, String firstRowContent) throws IOException {
        if (StrUtil.isBlank(fileName)) {
            //当前日期
            fileName = DateUtil.format(new DateTime(), DatePattern.CHINESE_DATE_TIME_FORMATTER);
        }

        setExcelResponse(response, fileName);

        // 设置表头字体样式
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 12); // 设置字体大小为16
        headWriteCellStyle.setWriteFont(headWriteFont);
        headWriteCellStyle.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());

        // 设置表头 和内容样式
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, (List<WriteCellStyle>) null);

        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), targetClass)
                .registerWriteHandler(new EasyExcelSheetWriteHandler(firstRowDocBool, firstRowContent))
                .registerWriteHandler(horizontalCellStyleStrategy)
                .relativeHeadRowIndex(1)
                .excelType(ExcelTypeEnum.XLSX)
                .build();

        WriteSheet writeSheet = EasyExcel.writerSheet(0, sheetName).build();

        excelWriter.write(dateList, writeSheet);
        excelWriter.finish();
    }
}

 4)其中自定导入第一行 导入内容依赖类

import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;

public class EasyExcelSheetWriteHandler implements SheetWriteHandler {

    /**
     * 首行是否为文档
     */
    private final Boolean firstRowDocBool;

    /**
     * 填写文件说明
     */
    private final String firstRowContent;

    public EasyExcelSheetWriteHandler(Boolean firstRowDocBool, String firstRowContent) {
        this.firstRowDocBool = firstRowDocBool;
        this.firstRowContent = firstRowContent;
    }

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        Workbook workbook = writeWorkbookHolder.getWorkbook();
        //Sheet sheet = workbook.getSheetAt(0);
        Sheet sheet = workbook.getSheet(writeSheetHolder.getSheetName());

        Row row1 = sheet.getRow(0);
        if (row1 == null) {
            row1 = sheet.createRow(0);
        }
        row1.setHeight((short) 500);//25*20   实际行高*20
        Cell cell1 = row1.getCell(0);
        if (cell1 == null) {
            cell1 = row1.createCell(0);
        }
        cell1.setCellValue(firstRowContent);

        CellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setVerticalAlignment(VerticalAlignment.BOTTOM);
        cellStyle.setFillBackgroundColor(IndexedColors.WHITE.getIndex());
        cellStyle.setBorderTop(BorderStyle.NONE);
        cellStyle.setBorderBottom(BorderStyle.NONE);
        cellStyle.setBorderLeft(BorderStyle.NONE);
        cellStyle.setBorderRight(BorderStyle.NONE);

        if (Boolean.TRUE.equals(firstRowDocBool)) {
            cellStyle.setAlignment(HorizontalAlignment.LEFT);
        } else {
            cellStyle.setAlignment(HorizontalAlignment.CENTER);
        }

        Font font = workbook.createFont();
        font.setBold(false);
        if (Boolean.TRUE.equals(firstRowDocBool)) {
            font.setFontName("宋体");
            font.setFontHeight((short) 220);//11*20   实际字号(字高)*20

        } else {
            font.setFontHeight((short) 360);//18*20   实际字号(字高)*20
            font.setFontName("黑体");
        }
        cellStyle.setFont(font);

        cell1.setCellStyle(cellStyle);
        sheet.addMergedRegionUnsafe(new CellRangeAddress(0, 0, 0, 15));
    }
}

2、easyExcel 导入逻辑

1)依赖于 fileutil,将  MultipartFile 转为file

File file = FileUtil.transferToFile(multipartFile);

2)拿到文件以后,导入实现逻辑如下 

EasyExcel.read(file, App.class, new ReadListener<App>() {
                        //临时存储数据对象
                        private final List<App> cachedDataList = ListUtils.newArrayList();

                        @Override
                        public void invoke(App data, AnalysisContext context) {
                            cachedDataList.add(data);
                        }

                        @Transactional
                        @Override
                        public void doAfterAllAnalysed(AnalysisContext context) {
                            StringBuffer errorCheckMsg = new StringBuffer();
                            AtomicBoolean isPass = new AtomicBoolean(true);

                            if (CollUtil.isEmpty(cachedDataList)) {
                                throw new CommonException("导入Excel列表为空");
                            }

                            //数据行是从第三行开始
                            AtomicInteger rowIndex = new AtomicInteger(3);
                            cachedDataList.forEach((app) -> {
                                //spring validator 验证每行数据是否合规
                                BindingResult result = new BeanPropertyBindingResult(app, "app");
                                validator.validate(app, result);
                                if (result.hasErrors()) {
                                    isPass.set(false);
                                    // 处理验证错误,例如返回错误消息
                                    errorCheckMsg.append("第").append(rowIndex).append("行:");
                                    StringBuilder sb = new StringBuilder();
                                    for (ObjectError error : result.getAllErrors()) {
                                        sb.append(error.getDefaultMessage()).append(";");
                                    }
                                    errorCheckMsg.append(sb).append("\n");
                                }
                                rowIndex.getAndIncrement();
                            });

                            if (isPass.get()) {
                                //mybatis 插入数据方法
                                saveBatch(cachedDataList);
                            }

                            if (!StrUtil.isEmpty(errorCheckMsg.toString())) {
                                throw new CommonException(errorCheckMsg.toString());
                            }
                        }
                    }).sheet()
                    .headRowNumber(2)//设置标题行的行号
                    .doRead();

3、easyExcel 自定义 list<map> 导出

1)导出工具类的使用

/**
     * 导出采购订单列表
     */
    @PreAuthorize("@ss.hasPermi('mes:ec:purorder:export')")
    @Log(title = "采购订单", businessType = BusinessType.EXPORT)
    @PostMapping("acsEnvMonitHis/export")
    public void export(BaseEntity baseEntity, HttpServletResponse response) throws IOException {
        String[][] headMap = {{"AA"}, {"BB"}
                , {"CC"}, {"DD"}};
        String[] dataStrMap = {"CC", "EE"};

        int[] witdhMap = {15, 20};
        List<Map<String, Object>> listDatas = 获取数据的service方法
        
        NoModelWriteData nmwDate = new NoModelWriteData();
        nmwDate.setFileName("历史生产数据");
        nmwDate.setHeadMap(headMap);
        nmwDate.setDataStrMap(dataStrMap);
        nmwDate.setWitdhArray(witdhMap);
        nmwDate.setDataList(listDatas);

        EasyExcelUtils.noModleExportExcel(nmwDate, response);
    }

2)依赖工具类:EasyExcelUtils

package com.hy.common.utils.poi;

import cn.hutool.core.util.ArrayUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.converters.ConverterKeyBuild;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import org.apache.poi.util.IOUtils;
import org.springframework.web.bind.annotation.RequestBody;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class EasyExcelUtils {

    //不创建对象的导出
    public static void noModleExportExcel(@RequestBody NoModelWriteData data, HttpServletResponse response) throws IOException {

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode(data.getFileName(), "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

        OutputStream out = null;
        try {
            out = response.getOutputStream();
            // 这里需要设置不关闭流
            ExcelWriter excelWriter = EasyExcel.write(out).charset(StandardCharsets.UTF_8).build();

            SqlDateConverter converterSqlDate = new SqlDateConverter();
            excelWriter.writeContext().currentWriteHolder().converterMap().put(ConverterKeyBuild.buildKey(converterSqlDate.supportJavaTypeKey()), converterSqlDate);
            excelWriter.writeContext().currentWriteHolder().converterMap().put(ConverterKeyBuild.buildKey(converterSqlDate.supportJavaTypeKey(), converterSqlDate.supportExcelTypeKey()), converterSqlDate);

            ExcelWriterSheetBuilder writerSheetBuilder = EasyExcel.writerSheet();
            writerSheetBuilder.registerConverter(new SqlDateConverter());
            writerSheetBuilder.registerConverter(new SqlTimeConverter());
            if (ArrayUtil.isNotEmpty(data.getWitdhArray())) {
                writerSheetBuilder.registerWriteHandler(new ColumnWidthStyleStrategy(data.getWitdhArray()));
            }

            WriteSheet writeSheet = writerSheetBuilder.build();
            writeSheet.setHead(head(data.getHeadMap()));
            writeSheet.setSheetName(data.getFileName());

            excelWriter.write(dataList(data.getDataList(), data.getDataStrMap()), writeSheet);
            excelWriter.finish();
        } catch (Exception e) {
            throw e;
        } finally {
            IOUtils.closeQuietly(out);
        }
    }

    //创建对象的导出
    public <T> void simpleWrite(@RequestBody SimpleWriteData data, Class<T> clazz, HttpServletResponse response) throws IOException {
        // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
        //response.setContentType("application/vnd.ms-excel");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode(data.getFileName(), "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), clazz).sheet(data.getFileName()).doWrite(data.getDataList());
    }

    //设置表头
    private static List<List<String>> head(String[][] headMap) {
        List<List<String>> list = new ArrayList<List<String>>();
        for (String[] headArray : headMap) {
            List<String> headList = new ArrayList<String>();
            for (String headStr : headArray) {
                headList.add(headStr);
            }
            list.add(headList);
        }
        return list;
    }

    //设置导出的数据内容
    private static List<List<Object>> dataList(List<Map<String, Object>> dataList, String[] dataStrMap) {
        List<List<Object>> list = new ArrayList<List<Object>>();
        for (Map<String, Object> map : dataList) {
            List<Object> data = new ArrayList<Object>();
            for (int i = 0; i < dataStrMap.length; i++) {
                data.add(map.get(dataStrMap[i]));
            }
            list.add(data);
        }
        return list;
    }
}

3)导出工具类、共依赖5个类,有不同作用,可根据实际情况删减

依赖3个类:2种参数,1个列宽策略

NoModelWriteData :导出数据,类型为List<MAP>
SimpleWriteData:导出数据,类型为List<对象>
ColumnWidthStyleStrategy:导出的列样式宽度策略

其中解决显示异常的数据类型依赖于2个类

SqlDateConverter :sqldate显示异常
SqlTimeConverter:sqltime显示异常
类1:NoModelWriteData :导出的第1种参数
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class NoModelWriteData implements Serializable {
    /** 文件名 **/
    private String fileName;
    /** 表头数组 **/
    private String[][] headMap;
    /** 对应数据字段数组 **/
    private String[] dataStrMap;
    /** 列宽数组 **/
    private int[] witdhArray;

    /** 数据集合 **/
    private List<Map<String, Object>> dataList;

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String[][] getHeadMap() {
        return headMap;
    }

    public void setHeadMap(String[][] headMap) {
        this.headMap = headMap;
    }

    public String[] getDataStrMap() {
        return dataStrMap;
    }

    public void setDataStrMap(String[] dataStrMap) {
        this.dataStrMap = dataStrMap;
    }

    public int[] getWitdhArray() {
        return witdhArray;
    }

    public void setWitdhArray(int[] witdhArray) {
        this.witdhArray = witdhArray;
    }

    public List<Map<String, Object>> getDataList() {
        return dataList;
    }

    public void setDataList(List<Map<String, Object>> dataList) {
        this.dataList = dataList;
    }

    @Override
    public String toString() {
        return "NoModelWriteData{" +
                "fileName='" + fileName + '\'' +
                ", headMap=" + Arrays.toString(headMap) +
                ", dataStrMap=" + Arrays.toString(dataStrMap) +
                ", witdhArray=" + Arrays.toString(witdhArray) +
                ", dataList=" + dataList +
                '}';
    }
}
类2:SimpleWriteData,导出的第2种参数
import java.io.Serializable;
import java.util.List;

public class SimpleWriteData implements Serializable {
    /** 文件名 **/
    private String fileName;
    /** 数据列表 **/
    private List<?> dataList;

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public List<?> getDataList() {
        return dataList;
    }

    public void setDataList(List<?> dataList) {
        this.dataList = dataList;
    }

    @Override
    public String toString() {
        return "SimpleWriteData{" +
                "fileName='" + fileName + '\'' +
                ", dataList=" + dataList +
                '}';
    }
}
 类3:ColumnWidthStyleStrategy :列宽度策略设置
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.style.column.AbstractHeadColumnWidthStyleStrategy;

import java.util.HashMap;
import java.util.Map;

public class ColumnWidthStyleStrategy extends AbstractHeadColumnWidthStyleStrategy {

    private Map<Integer,Integer> columnWidth = new HashMap<>();

    public ColumnWidthStyleStrategy() {
    }

    public ColumnWidthStyleStrategy(int[] widthArray) {
        for (int i = 0; i < widthArray.length; i++) {
            columnWidth.put(i,widthArray[i]);
        }
    }

    @Override
    protected Integer columnWidth(Head head, Integer columnIndex) {
        return columnWidth.getOrDefault(columnIndex,25);
    }
}
 类四:SqlDateConverter:为了 sql.date 类型在excel中显示正常
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;

import java.math.BigDecimal;
import java.sql.Date;
import java.text.ParseException;

/**
 * Date and string converter
 *
 * @author Jiaju Zhuang
 */
public class SqlDateConverter implements Converter<Date> {
    @Override
    public Class<?> supportJavaTypeKey() {
        return Date.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    @Override
    public Date convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty,
        GlobalConfiguration globalConfiguration) throws ParseException {
        switch (cellData.getType()) {
            case NUMBER:
                BigDecimal numberValue = cellData.getNumberValue();
                return new Date(numberValue.longValue());
            case STRING:
                String stringValue = cellData.getStringValue();
                if (StrUtil.isBlank(stringValue) || "NA".equals(stringValue)) {
                    return null;
                }
                try {
                    return new Date(DateUtil.parse(cellData.getStringValue()).getTime());
                } catch (NumberFormatException e) {
                    return null;
                }
            default:
                return null;
        }
    }

    @Override
    public WriteCellData<?> convertToExcelData(Date value, ExcelContentProperty contentProperty,
        GlobalConfiguration globalConfiguration) {
        if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) {
            return new WriteCellData<>(DateUtil.formatDate(value));
        } else {
            return new WriteCellData<>(DateUtil.format(value, contentProperty.getDateTimeFormatProperty().getFormat()));
        }
    }
}
类五:SqlTimeConverter :为了 sql.time 类型在excel中显示正常
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;

import java.math.BigDecimal;
import java.sql.Time;
import java.text.ParseException;

/**
 * Date and string converter
 *
 * @author Jiaju Zhuang
 */
public class SqlTimeConverter implements Converter<Time> {
    @Override
    public Class<?> supportJavaTypeKey() {
        return Time.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    @Override
    public Time convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty,
        GlobalConfiguration globalConfiguration) throws ParseException {
        switch (cellData.getType()) {
            case NUMBER:
                BigDecimal numberValue = cellData.getNumberValue();
                return new Time(numberValue.longValue());
            case STRING:
                String stringValue = cellData.getStringValue();
                if (StrUtil.isBlank(stringValue) || "NA".equals(stringValue)) {
                    return null;
                }
                try {
                    return new Time(DateUtil.parseTime(cellData.getStringValue()).getTime());
                } catch (NumberFormatException e) {
                    return null;
                }
            default:
                return null;
        }
    }

    @Override
    public WriteCellData<?> convertToExcelData(Time value, ExcelContentProperty contentProperty,
        GlobalConfiguration globalConfiguration) {
        if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) {
            return new WriteCellData<>(DateUtil.formatTime(value));
        } else {
            return new WriteCellData<>(DateUtil.format(value, contentProperty.getDateTimeFormatProperty().getFormat()));
        }
    }
}

4、你可能用到其他教程

1)poi 导出自定义样式excel

springboot、springmvc,excel上传解析、下载excel工具类_mediatype中适合excel-CSDN博客文章浏览阅读376次。工具类共7个方法: /** * 1)对外方法:解析上传的excel,只含一个sheet kly * @example: List strArrayList = ExcelUtil.getExcelData(MultipartFile); */ /** * 2)对外方法:获取第几个sheet页的数据..._mediatype中适合excel[]>https://blog.csdn.net/qq_26408545/article/details/103713665

2)poi 导出word

POI 导出横版A4word,并设置excel宽度(固定不变形)_a4 poi 宽度设置-CSDN博客文章浏览阅读2.6k次,点赞4次,收藏8次。1.maven依赖 org.apache.poipoi3.17 &_a4 poi 宽度设置https://blog.csdn.net/qq_26408545/article/details/110669104

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1521735.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【论文阅读】IRNet:具有像素间关系的实例分割的弱监督学习

【论文阅读】IRNet:具有像素间关系的实例分割的弱监督学习 文章目录 【论文阅读】IRNet:具有像素间关系的实例分割的弱监督学习一、介绍二、联系工作三、方法四、实验结果 Weakly Supervised Learning of Instance Segmentation with Inter-pixel Relations 本文提出了一种以图…

2024043期传足14场胜负前瞻

2024043期售止时间为3月17日&#xff08;周日&#xff09;21点30分&#xff0c;敬请留意&#xff1a; 本期深盘多&#xff0c;1.5以下赔率1场&#xff0c;1.5-2.0赔率7场&#xff0c;其他场次是平半盘、平盘。本期14场整体难度中等偏上。以下为基础盘前瞻&#xff0c;大家可根据…

Java后端面试经验分享,~纯分享

本文将从面试、工作、学习三个方面分享最近面试的一些心得以及以后发展的一些规划&#xff0c;仅供参考&#xff0c;哈哈&#xff0c;毕竟本人也很菜&#xff0c;因为菜才要多学习。一会儿也会分享两本Java面试题库&#xff08;题库是b站大学找的&#xff0c;一会儿我也会分享出…

[Vue]组件间通讯

Vue组件间通讯 父子间通讯 非父子间通讯 父子间通讯 父组件通过 props 将数据传递给子组件父向子传值步骤 给子组件以添加属性的方式传值 子组件内部通过props接收 模板中直接使用 props接收 子组件利用 $emit 通知父组件修改更新 $emit触发事件&#xff0c;给父组件…

leetcode代码记录(组合

目录 1. 题目&#xff1a;2. 我的代码&#xff1a;小结&#xff1a; 1. 题目&#xff1a; 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;n 4, k 2 输出&#xff1a; [ […

python知识点总结(一)

这里写目录标题 一、什么是WSGI,uwsgi,uWSGI1、WSGI2、uWSGI3、uwsgi 二、python中为什么没有函数重载&#xff1f;三、Python中如何跨模块共享全局变量?四、内存泄露是什么?如何避免?五、谈谈lambda函数作用?六、写一个函数实现字符串反转&#xff0c;尽可能写出你知道的所…

【Linux C | 多线程编程】线程的基础知识

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

MySQL语法分类 DQL(1)基础查询

//语法 select 字段列表 from 表名列表 where条件列表 group by分组字段 having 分组后的条件 order by排序 limit 分页限定为了更好的学习这里给出基本表数据用于查询操作 create table student (id int, name varchar(20), age int, sex varchar(5),address varchar(100),ma…

Go语言加密技术实战:掌握encoding/pem库

Go语言加密技术实战&#xff1a;掌握encoding/pem库 引言PEM格式简介核心组成常见用途 Go语言的encoding/pem库概览核心功能使用场景 开始使用encoding/pem读取PEM文件编码为PEM格式 深入理解PEM编码自定义PEM头部信息 使用encoding/pem解码PEM文件PEM文件的加密与解密加密私钥…

代码随想录训练营Day25:● 216.组合总和III ● 17.电话号码的字母组合

216.组合总和III 题目链接 https://leetcode.cn/problems/combination-sum-iii/description/ 题目描述 思路 自己写的效率会慢一些&#xff0c;而且没有用到剪枝 class Solution {List<List<Integer>> list new ArrayList<>();List<Integer> lis…

基于PIESDK的二次开发--土壤水反演系统

目录 系统演示数据获取算法封装系统 系统演示 数据获取 基于TVDI的土壤水分反演需要有地表温度和植被指数数据&#xff0c;该部分参考Landsat计算TVDI进行干旱监测&#xff08;二&#xff09; 得到两张TIF影像 算法封装 初始的.py代码参数是直接指定的&#xff0c;然而在封…

【Javascript编程实操06】1、反转数组和字符串 2、将二维数组转一维数组

前言 1、反转数组和字符串 代码&#xff1a; 实现效果&#xff1a; 2、将二维数组转一维数组 代码&#xff1a; 实现效果&#xff1a; 总结 前言 本次主要是针对Javascript阶段的字符串与数组的实操练习&#xff0c;共有2个实操&#xff0c;大家可以在实操的过程中更加深…

ARM 寄存器学习:(一)arm多种模式下得寄存器

一.ARM7种状态以及每种状态的寄存器&#xff1a; ARM 处理器共有 7 种不同的处理器模式&#xff0c;在每一种处理器模式中可见的寄存器包括 15 个通用寄存器( R0~R14)、一个或两个(User和Sys不是异常模式&#xff0c;没有spsr寄存器)状态寄存器&#xff08;cpsr和spsr&…

想兼职赚钱?盘点6个靠谱兼职,赚钱更轻松!

1&#xff0c;微头条搬砖 微头条搬砖是一个门槛不高的赚钱方式&#xff0c;而且不需要你有多么好的原创能力&#xff0c;去收集一些热门文章的素材进行文章伪原创&#xff0c;十分钟就能搞定&#xff0c;只要你的文章有爆点&#xff0c;足够吸人眼球&#xff0c;就能够获取不低…

Web核心,HTTP,tomcat,Servlet

1&#xff0c;JavaWeb技术栈 B/S架构:Browser/Server&#xff0c;浏览器/服务器架构模式&#xff0c;它的特点是&#xff0c;客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务器端。浏览器只需要请求服务器&#xff0c;获取Web资源&#xff0c;服务器把Web资源…

Linux服务器(Debian系)包含UOS安全相关巡检shell脚本

#!/bin/bash# Define output file current_date$(date "%Y%m%d") # Gets the current date in YYYYMMDD format output_file"server_security_inspection_report_${current_date}.txt"# Empty the file initially echo > $output_file# 获取巡检时间 (…

蓝桥杯刷题(九)

1.三国游戏 代码 #输入数据 nint(input()) Xlilist(map(int,input().split())) Ylilist(map(int,input().split())) Zlilist(map(int,input().split())) #分别计算X-Y-Z/Y-Z-X/Z-X-Y并排序 newXli sorted([Xli[i] - Yli[i] - Zli[i] for i in range(n)],reverseTrue) newYli …

Pikachu 靶场搭建

文章目录 环境说明1 Pikachu 简介2 Pikachu 安装 环境说明 操作系统&#xff1a;Windows 10PHPStudy 版本: 8.1.1.3Apache 版本&#xff1a;2.4.39MySQL 版本 5.7.26 1 Pikachu 简介 Pikachu是一个使用“PHP MySQL” 开发、包含常见的Web安全漏洞、适合Web渗透测试学习人员练…

腾讯云轻量2核4G5M服务器卡不卡?性能怎么样?

腾讯云轻量2核4G5M带宽服务器支持多少人在线访问&#xff1f;5M带宽下载速度峰值可达640KB/秒&#xff0c;阿腾云以搭建网站为例&#xff0c;假设优化后平均大小为60KB&#xff0c;则5M带宽可支撑10个用户同时在1秒内打开网站&#xff0c;并发数为10&#xff0c;经阿腾云测试&a…

C++算法学习心得八.动态规划算法(4)

1.零钱兑换&#xff08;322题&#xff09; 题目描述&#xff1a; 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1。 你可以认为每种硬币的数量是无限的。…