首页 > 其他分享 >POI之EXCEL导出封装(未测试)

POI之EXCEL导出封装(未测试)

时间:2024-04-05 19:22:05浏览次数:14  
标签:return get List POI EXCEL param Integer 封装 public

基础类描述

  1. ExcelWriter(导出工具类)
  2. Query(通用查询)
  3. Consumer(函数参数)
  4. SpringBeanUtil(获取bean)

代码

ExcelWriter


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.PageUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.util.ListUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.itxl.common.utils.SpringBeanUtil;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @authar liuWei
 * @ @date 2024/3/30
 */
public class ExcelWriter <T>{
    private HttpServletResponse response;

    private ServletOutputStream outputStream;

    private boolean memory = false;

    private boolean multiThread = false;

    private String fileName = "file";

    private Workbook workbook = new SXSSFWorkbook();

    private String curSheetName = "sheet";

    /**
     * 响应文件流类型
     */
    private static final String CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    /**
     * 响应头文件名编码格式
     */
    private static final String ENCODE = "UTF-8";

    private AtomicInteger curRowIndex;

    private Integer total;

    private Integer sheetNo = 1;

    private static final Integer sheetMaxNum = 1000000;

    private List<List<Integer>> widths;

    private List<List<Integer>> heights;

    private List<List<Integer>> cellStyleIndex;

    private List<CellStyle> cellStyles;

    private Integer defaultColumnWidth = 20;

    private Integer defaultRowHeight = 20;

    private List<List<Integer>> cellValueIndex;

    private List<String> cellValues;

    private List<List<Integer>> mergeInfo;

    private List<List<Integer>> dropDownBoxIndex;

    private List<List<String>> dropDownBoxDatas;

    private List<List<Integer>> chartAnchor;

    private List<byte[]> chartBytes;

    public ExcelWriter(HttpServletResponse response) {
        this.response = response;
    }

    /**
     * 使用内存缓存(加快速度)
     * @return
     */
    public ExcelWriter<T> memory(){
        workbook = new XSSFWorkbook();
        return this;
    }

    /**
     * 设置文件名
     * @param fileName
     * @return
     */
    public ExcelWriter<T> setFileName(String fileName){
        this.fileName = fileName;
        return this;
    }

    /**
     * 初始化响应流
     * @return
     * @throws IOException
     */
    public ExcelWriter<T> initResponse() throws IOException {
        response.setContentType(CONTENT_TYPE);
        response.setCharacterEncoding(ENCODE);
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        fileName = URLEncoder.encode(fileName, ENCODE).replaceAll("\\+", "%20");
        response.setHeader("fileName",fileName+".xlsx");
        this.outputStream = response.getOutputStream();
        return this;
    }

    /**
     * 分页
     * @param total
     * @return
     */
    public ExcelWriter<T> paging(Integer total){
        this.total = total;
        return this;
    }

    /**
     * 开启多线程
     * @param total
     * @return
     */
    public ExcelWriter<T> multiThread(Integer total){
        this.multiThread = true;
        return paging(total);
    }

    /**
     * 设置头
     * @param heads
     * @param rowIndex
     * @param colIndex
     * @return
     */
    public ExcelWriter<T> setHead(List<String> heads,Integer rowIndex, Integer colIndex){
        for (int i = 0; i < heads.size(); i++) {
            setCell(heads.get(i),rowIndex,colIndex+i).setHeadStyle(rowIndex,colIndex+i);
        }
        return this;
    }

    /**
     * 设置单元格内容
     * @param value
     * @param rowIndex
     * @param colIndex
     * @return
     */
    public ExcelWriter<T> setCell(String value,Integer rowIndex,Integer colIndex){
        if (CollUtil.isEmpty(cellValues)){
            cellValues = new ArrayList<>();
        }
        if (CollUtil.isEmpty(cellValueIndex)){
            cellValueIndex = new ArrayList<>();
        }
        cellValues.add(value);
        cellValueIndex.add(ListUtils.newArrayList(rowIndex,colIndex));
        return this;
    }

    /**
     * 设置单元格内容
     * @param value
     * @param rowIndex
     * @param colIndex
     * @return
     */
    private ExcelWriter<T> doSetCell(String value,Integer rowIndex,Integer colIndex){
        Sheet sheet = getSheet();
        Row row = getRow(sheet,rowIndex);
        Cell cell = getCell(row, colIndex);
        cell.setCellValue(value);
        return this;
    }

    /**
     * 获取sheet
     * @return
     */
    public Sheet getSheet(){
        Sheet sheet = workbook.getSheet(curSheetName + sheetNo);
        if (sheet == null){
            sheet = workbook.createSheet(curSheetName + sheetNo);
        }
        return sheet;
    }

    /**
     * 切换sheet
     * @param sheetName
     * @return
     */
    public ExcelWriter<T> setCurSheetName(String sheetName){
        this.curSheetName = sheetName;
        return this;
    }

    /**
     * 获取Row
     * @param sheet
     * @param rowIndex
     * @return
     */
    private Row getRow(Sheet sheet,Integer rowIndex){
        Row row = sheet.getRow(rowIndex);
        if (row == null){
            row = sheet.createRow(rowIndex);

        }
        return row;
    }

    /**
     * 获取cell
     * @param row
     * @param colIndex
     * @return
     */
    private Cell getCell(Row row,Integer colIndex){
        Cell cell = row.getCell(colIndex);
        if (cell == null){
            cell = row.getCell(colIndex);
        }
        return cell;
    }

    /**
     * 获取空白单元格样式,如果需要使用memory方法,,需要使用memory后调用
     * @return
     */
    public CellStyle getBlankCellStyle(){
        return workbook.createCellStyle();
    }

    /**
     * 设置单元格样式
     * @param rowIndex
     * @param colIndex
     * @param cellStyle
     * @return
     */
    public ExcelWriter<T> setCellStyle(Integer rowIndex, Integer colIndex, CellStyle cellStyle){
        if (CollUtil.isEmpty(cellStyleIndex)){
            cellStyleIndex = new ArrayList<>();
        }
        if (CollUtil.isEmpty(cellStyles)){
            cellStyles = new ArrayList<>();
        }
        cellStyleIndex.add(ListUtils.newArrayList(rowIndex,colIndex));
        cellStyles.add(cellStyle);
        return this;
    }

    /**
     * 设置头样式
     * @param rowIndex
     * @param colIndex
     * @return
     */
    private ExcelWriter<T> setHeadStyle(Integer rowIndex, Integer colIndex){
        CellStyle cellStyle = getBlankCellStyle();
        //设置头样式
        return setCellStyle(rowIndex,colIndex,cellStyle);
    }

    /**
     * 设置列宽
     * @param col
     * @param width
     * @return
     */
    public ExcelWriter<T> setColumnWidth(Integer col,Integer width){
        if (CollUtil.isEmpty(widths)){
            widths = new ArrayList<>();
        }
        widths.add(ListUtils.newArrayList(col,width));
        return this;
    }

    /**
     * 设置列宽
     * @param cols 0:列,1:列宽
     * @return
     */
    public ExcelWriter<T> setColumnWidth(List<List<Integer>> cols){
        if (CollUtil.isEmpty(widths)){
            widths = new ArrayList<>();
        }
        widths.addAll(cols);
        return this;
    }

    /**
     * 设置行高
     * @param rows 0:行,1:行高
     * @return
     */
    public ExcelWriter<T> setRowHeight(List<List<Integer>> rows){
        if (CollUtil.isEmpty(heights)){
            heights = new ArrayList<>();
        }
        heights.addAll(rows);
        return this;
    }

    /**
     * 设置行高,列宽
     * @param axisInfo 0:行,1:行高,2:列,3:列宽
     * @return
     */
    public ExcelWriter<T> setRowHeightAndColumnWidth(List<List<Integer>> axisInfo){
        for (List<Integer> axis : axisInfo) {
            setRowHeightAndColumnWidth(axis.get(0),axis.get(1),axis.get(2),axis.get(3));
        }
        return this;
    }

    /**
     * 设置行高,列宽
     * @param row
     * @param rowHeight
     * @param col
     * @param colWidth
     * @return
     */
    public ExcelWriter setRowHeightAndColumnWidth(Integer row,Integer rowHeight,Integer col,Integer colWidth){
        return setRowHeight(row, rowHeight).setColumnWidth(col, colWidth);
    }

    /**
     * 设置默认列宽
     * @param height
     * @return
     */
    public ExcelWriter<T> setDefaultRowHeight(Integer height){
        this.defaultRowHeight = height;
        return this;
    }

    /**
     * 设置默认列宽
     * @param width
     * @return
     */
    public ExcelWriter<T> setDefaultColumnWidth(Integer width){
        this.defaultColumnWidth = width;
        return this;
    }

    /**
     * 设置默认行高,列宽
     * @param height
     * @param width
     * @return
     */
    public ExcelWriter<T> setDefaultRowHeightAndColumnWidth(Integer height,Integer width){
        return setDefaultColumnWidth(width).setDefaultRowHeight(height);
    }

    /**
     * 设置行高
     * @param rowIndex
     * @param height
     * @return
     */
    public ExcelWriter<T> setRowHeight(Integer rowIndex,Integer height){
        heights.add(ListUtils.newArrayList(rowIndex,height));
        return this;
    }


    /**
     * 写数据
     * @param query
     * @param row
     * @param col
     * @return
     * @throws IOException
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public ExcelWriter<T> write(Query<List<List<String>>> query,Integer row,Integer col) throws IOException, ExecutionException, InterruptedException {
        if (curRowIndex == null){
            curRowIndex = new AtomicInteger(row);
        }
        if (total == null){
             write(query.accept(),curRowIndex.get(),col);
             return this;
        }
        int totalPage = PageUtil.totalPage(total, query.getPageSize());
        AtomicInteger pageNum = new AtomicInteger(0);
        if (!multiThread){
            write(query, curRowIndex.get(), col, pageNum,totalPage);
            return this;
        }
        ThreadPoolExecutor poolExecutor = SpringBeanUtil.getBean(ThreadPoolExecutor.class);
        List<Future<?>> futures = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            Future<?> future =poolExecutor.submit(() -> {
                write(query, curRowIndex.get(), col, pageNum,totalPage);
            });
            futures.add(future);
        }
        for (Future<?> future : futures) {
            future.get();
        }
        return this;
    }

    /**
     * 写数据
     * @param data
     * @param row
     * @param col
     * @throws IOException
     */
    public void write(List<List<String>> data, Integer row, Integer col) throws IOException {
        if (curRowIndex == null) {
            curRowIndex = new AtomicInteger(row);
        }
        if (curRowIndex.get() + data.size() > sheetMaxNum){
            List<List<String>> left = ListUtil.sub(data, 0, sheetMaxNum - curRowIndex.get());
            doWrite(left,curRowIndex.get(), col);
            data = ListUtil.sub(data, sheetMaxNum - curRowIndex.get(), data.size());
            curRowIndex.set(0);
            sheetNo++;
        }
        doWrite(data,curRowIndex.get(), col);
    }

    private void write(Query<List<List<String>>> query, Integer row, Integer col,  AtomicInteger pageNum,int totalPage) {
        while (pageNum.get() < totalPage){
            query.setPageNum(pageNum.incrementAndGet());
            List<List<String>> accept = query.accept();
            try {
                write(accept, row+(pageNum.get()-1)*query.getPageSize(), col);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            query.removePage();
        }
    }

    /**
     * 写数据
     * @return
     * @throws IOException
     */
    public ExcelWriter<T> write() throws IOException {
        workbook.write(outputStream);
        return this;
    }

    /**
     * 写数据
     * @param data
     * @param row
     * @param col
     * @throws IOException
     */
    private void doWrite(List<List<String>> data, Integer row, Integer col) throws IOException {
        synchronized (outputStream){
            for (int i = 0; i < data.size(); i++) {
                for (int j = 0; j < data.get(i).size(); j++) {
                    doSetCell(data.get(i).get(j),row+i,col+j);
                }
            }
            curRowIndex.set(row+data.size());
            write();
        }
    }

    private List<List<String>> parseData(List<T> datas,List<String> fields){
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<List<String>> res = new ArrayList<>(datas.size());
        for (T data : datas) {
            JSONObject json = JSONUtil.parseObj(data);
            List<String> objects = new ArrayList<>(fields.size());
            for (String field : fields) {
                Object o = json.get(field);
                if (o == null){
                    o = "";
                }else if (o instanceof Date){
                    o = format.format(o);
                }else{
                    o = o.toString();
                }
                objects.add(o.toString());
            }
            res.add(objects);
        }
        return res;
    }

    /**
     * 编译基础信息
     * @return
     */
    public ExcelWriter<T> builder(){
        Sheet sheet = getSheet();
        sheet.setDefaultColumnWidth(defaultColumnWidth * 256);
        sheet.setDefaultRowHeight(defaultRowHeight.shortValue());
        if (widths != null){
            for (List<Integer> width : widths) {
                sheet.setColumnWidth(width.get(0),width.get(1));
            }
        }
        if (heights != null){
            for (List<Integer> height : heights) {
                Row row = getRow(sheet, height.get(0));
                row.setHeight(height.get(1).shortValue());
            }
        }
        if (cellStyleIndex != null){
            for (int i = 0; i < cellStyleIndex.size(); i++) {
                List<Integer> index = cellStyleIndex.get(i);
                CellStyle cellStyle = cellStyles.get(i);
                Cell cell = getCell(getRow(sheet, index.get(0)), index.get(1));
                cell.setCellStyle(cellStyle);
            }
        }
        if (cellValueIndex != null){
            for (int i = 0; i < cellValueIndex.size(); i++) {
                List<Integer> index = cellValueIndex.get(i);
                String value = cellValues.get(i);
                doSetCell(value,index.get(0),index.get(1));
            }
        }
        if (mergeInfo != null){
            for (List<Integer> merge : mergeInfo) {
                doMerge(merge.get(0),merge.get(1),merge.get(2),merge.get(3));
            }
        }
        if (dropDownBoxDatas != null){
            for (int i = 0; i < dropDownBoxIndex.size(); i++) {
                List<Integer> index = dropDownBoxIndex.get(i);
                List<String> data = dropDownBoxDatas.get(i);
                doSetDropDownBox(data,index.get(0),index.get(1),index.get(2),index.get(3));
            }
        }
        if (chartAnchor != null){
            for (int i = 0; i < chartAnchor.size(); i++) {
                List<Integer> anchorIndex = chartAnchor.get(i);
                byte[] bytes = chartBytes.get(i);
                Drawing<?> drawing =sheet.createDrawingPatriarch();
                ClientAnchor anchor = drawing.createAnchor(anchorIndex.get(0), anchorIndex.get(1), anchorIndex.get(2), anchorIndex.get(3), anchorIndex.get(4),
                        anchorIndex.get(5), anchorIndex.get(6), anchorIndex.get(7));
                // 参数分别代表 dx1, dy1, dx2, dy2, col1, row1, col2, row2
                // 参数解释:
                // dx1, dy1 - 图片左上角相对于单元格左上角的偏移量(以EMU为单位)
                // dx2, dy2 - 图片右下角相对于单元格左上角的偏移量(以EMU为单位)
                // col1, row1 - 图片左上角的起始单元格位置
                // col2, row2 - 图片右下角的结束单元格位置
                // 注意:EMU是Excel内部使用的单位,1英寸 = 914400 EMU

                // 将图片添加到Workbook中,并获取图片的索引
                int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
                // 创建图片并添加到Drawing对象中
                drawing.createPicture(anchor, pictureIdx);
            }
        }
        return this;
    }

    /**
     * 设置图表
     * @param bytes 图表数据
     * @param dx1
     * @param dy1
     * @param dx2
     * @param dy2
     * @param col1
     * @param row1
     * @param col2
     * @param row2
     * @return
     */
    public ExcelWriter<T> setChart(byte[] bytes,int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2){
        if (chartAnchor == null){
            chartAnchor = new ArrayList<>();
        }
        if (chartBytes == null){
            chartBytes = new ArrayList<>();
        }
        chartBytes.add(bytes);
        chartAnchor.add(ListUtils.newArrayList(dx1,dy1,dx2,dy2,col1,row1,col2,row2));
        return this;
    }

    /**
     * 合并单元格
     * @param firstRow
     * @param lastRow
     * @param firstCol
     * @param lastCol
     */
    private void doMerge(Integer firstRow, Integer lastRow, Integer firstCol, Integer lastCol){
        CellRangeAddress address = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
        getSheet().addMergedRegion(address);
    }

    /**
     * 合并单元格
     * @param firstRow
     * @param lastRow
     * @param firstCol
     * @param lastCol
     * @return
     */
    public ExcelWriter<T> merge(Integer firstRow, Integer lastRow, Integer firstCol, Integer lastCol){
        if (mergeInfo == null){
            mergeInfo = new ArrayList<>();
        }
        mergeInfo.add(ListUtils.newArrayList(firstRow,lastRow,firstCol,lastCol));
        return this;
    }

    /**
     * 合并单元格
     * @param mergeInfo
     * @return
     */
    public ExcelWriter<T> merge(List<List<Integer>> mergeInfo){
        if (this.mergeInfo == null){
            this.mergeInfo = new ArrayList<>();
        }
        this.mergeInfo.addAll(mergeInfo);
        return this;
    }

 ;    /**
     * 设置下拉框
     * @param data
     * @param firstRow
     * @param lastRow
     * @param firstCol
     * @param lastCol
     * @return
     */
    public ExcelWriter<T> setDropDownBox(List<String> data,Integer firstRow, Integer lastRow, Integer firstCol, Integer lastCol){
        if (dropDownBoxIndex == null){
            dropDownBoxIndex = new ArrayList<>();
        }
        if (dropDownBoxDatas == null){
            dropDownBoxDatas = new ArrayList<>();
        }
        dropDownBoxIndex.add(ListUtils.newArrayList(firstRow,lastRow,firstCol,lastCol));
        dropDownBoxDatas.add(data);
        return this;
    }

    /**
     * 设置下拉框
     * @param data
     * @param firstRow
     * @param lastRow
     * @param firstCol
     * @param lastCol
     */
    public void doSetDropDownBox(List<String> data,Integer firstRow, Integer lastRow, Integer firstCol, Integer lastCol){
        Sheet sheet = getSheet();
        DataValidationHelper validationHelper = sheet.getDataValidationHelper();

        // 创建列表约束
        DataValidationConstraint constraint = validationHelper.createExplicitListConstraint(data.toArray(new String[0]));

        // 创建单元格范围,这里设置的是A1单元格
        CellRangeAddressList addressList = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);

        // 创建数据验证对象
        DataValidation validation = validationHelper.createValidation(constraint, addressList);
        // 处理Excel中的错误警告
        validation.setShowErrorBox(true);
        validation.createErrorBox("错误", "您必须选择下拉列表中的选项之一。");

        // 将数据验证添加到工作表中
        sheet.addValidationData(validation);
    }





}

Query


import org.itxl.common.utils.Consumer;

/**
 * @authar liuWei
 * @ @date 2024/3/25
 */
public abstract class Query<T> implements Consumer<T> {

    private final ThreadLocal<Integer> local = new ThreadLocal<>();

    private Integer pageSize = 10000;

    public void setPageNum(Integer pageNum){
        local.set(pageNum);
    }

    public Integer getPageNum(){
       return local.get();
    }

    public void removePage(){
        local.remove();
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        if (pageSize == null){
            return;
        }
        this.pageSize = pageSize;
    }

    @Override
    public T accept() {
        return andThen();
    }
}

Consumer


/**
 * @authar  liuWei
 * 通用函数参数
 * @param <T>
 */
public interface Consumer<T>{
    /**
     * 方法实现
     * @return T
     */
    T andThen();

    /**
     * 方法执行
     * @return T
     */
    T accept();
}

SpringBeanUtil

package org.itxl.common.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * @authar liuWei
 * @ @date 2024/2/2
 */
@Component
public class SpringBeanUtil  implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static Object getBean(String beanName) {
        return applicationContext.getBean(beanName);
    }

    public static <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }

    public static <T> T getBean(String beanName, Class<T> clazz) {
        return applicationContext.getBean(beanName, clazz);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (SpringBeanUtil.applicationContext == null){
            SpringBeanUtil.applicationContext = applicationContext;
        }
    }
}

关于导出工具类ExcelWriter对于图表的的导出方法的使用

  1. 通过JFreeChart绘制图片,转为byte数据调用方法使用

标签:return,get,List,POI,EXCEL,param,Integer,封装,public
From: https://www.cnblogs.com/1024-lzy/p/18116085

相关文章

  • easyExcel通用导出(非注解,多线程)
    1、基础类描述ExcelWriter(导出工具类)Query(通用查询)Consumer(函数参数)SpringBeanUtil(获取bean)2、代码ExcelWriterimportcn.hutool.core.collection.CollUtil;importcn.hutool.core.collection.ListUtil;importcn.hutool.core.util.PageUtil;importcn.hutool.core.u......
  • 【Java】轻量Excel读写框架学习
     参考黑马教程:https://www.bilibili.com/video/BV1eA41157va?p=5写着写着发现有更好的Demo案例:https://cloud.tencent.com/developer/article/1966065所需依赖:<dependency><groupId>org.apache.tika</groupId><artifactId>tika-core</artifa......
  • Qt 处理excel
    处理Excel文件在Qt中通常涉及到使用第三方库,因为Qt本身并不直接支持Excel文件的读写。下面我将提供一个使用QAxObject(ActiveX封装)来操作Excel的基本代码示例。请注意,这个方法要求你的系统上安装有MicrosoftExcel。首先,确保你的Qt项目配置中包含了ActiveQt模块。在你的.pro文......
  • C# NPOI 读取EXCEL数据后转化为DataTable
    XSSF是用于.xlsx(2007以后版本)HSSF是用于.xls(2007以前版本)//也可以根据后缀名自动切换IWorkbookIWorkbookworkbook;if(fileExt==".xlsx"){workbook=newXSSFWorkbook(fs);}elseif(fileExt==".xls"||fileExt==".xlt"){workbook=newHSSFWorkboo......
  • 【漏洞复现】宏景人力资源信息管理系统 DisplayExcelCustomReport 任意文件读取漏洞
    免责声明:文章来源互联网收集整理,文章仅供参考,此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失,均由使用者......
  • flask 装饰器 AssertionError: View function mapping is overwriting an existing en
    1问题描述写了一个登陆认证装饰器,部分试图,只有用户登陆才能访问deflogin_wrapper(func):definner(*args,**kwargs):"""判断是否登陆若是进入视图函数否则重定向到登陆页面"""if......
  • Excel、PowerQuery 和 ChatGPT 终极手册(上)
    原文:UltimateChatGPTHandbookforEnterprises译者:飞龙协议:CCBY-NC-SA4.0序言在不断发展的数据管理和分析领域中,掌握Excel的查找功能不仅是一种技能,更是高效数据处理的基石。《使用PowerQuery和ChatGPT的终极Excel》不仅仅是一本书;它是为数据爱好者、Excel爱好......
  • 使用 ChatGPT 集成精通高级 Excel(一)
    原文:MasteringAdvancedExcel-WithChatGPTIntegration译者:飞龙协议:CCBY-NC-SA4.0前言欢迎阅读我的书!在这本全面指南中,我们将探索Excel、VisualBasicforApplications(VBA)和ChatGPT这三大强大工具的结合。这些工具结合了数据分析、自动化和对话式人工智能的力量,让......
  • 使用 ChatGPT 集成精通高级 Excel(二)
    原文:MasteringAdvancedExcel-WithChatGPTIntegration译者:飞龙协议:CCBY-NC-SA4.0第九章数据透视表介绍数据透视表是一种基于交互式工作表的表格,可以快速汇总大量数据,使用您选择的格式和计算方法。它被称为数据透视表,因为您可以围绕核心数据区域旋转其行和列标题,以便......
  • 使用 ChatGPT 集成精通高级 Excel(三)
    原文:MasteringAdvancedExcel-WithChatGPTIntegration译者:飞龙协议:CCBY-NC-SA4.0第十五章将按钮分配给宏介绍在本章中,我们将探讨在Excel中将按钮分配给宏的过程。通过在快速访问工具栏和Excel工作表上创建按钮,我们可以自动化任务,提高效率并简化��杂操作。加入我们......