SpringBoot发邮件(带附件)

1、需求

每个月月初需要对各部门的项目预算、进度、金额使用情况进行统计,统计完成后将报表通过邮件发送到指定的领导邮箱,项目基于SpringBoot实现,那就找SpringBoot发邮件的组件吧

2、找解决办法

通过在bing.cn搜索SpringBoot发邮件带附件,很容易就找到很多前辈们分享的方案

3、实现

<!-- Mail -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

在Service中依赖注入

@Resource
private JavaMailSender javaMailSender;
package com.quality.centre.base.alert.pojo.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @Description: 发送邮件的实体类
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ToEmail implements Serializable {

    /**
     * 邮件接收方,可多人
     */
    private String[] tos;

    /**
     * 邮件主题
     */
    private String subject;

    /**
     * 邮件内容
     */
    private String content;

    /**
     * 告警颜色
     */
    private String alertColor;

    /**
     * 描述
     */
    private String remark;

}

 通过生产临时文件的方式发送,需要注意发送完成后删除临时文件,否则会产生很多垃圾文件

@Override
    public R<?> sendEmailFile(ToEmail toEmail, File file) throws MessagingException {
        MimeMessage message = javaMailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(message,true);
        mimeMessageHelper.setFrom(emailUsername);
        mimeMessageHelper.setTo(toEmail.getTos());
        mimeMessageHelper.setSubject(toEmail.getSubject());
        mimeMessageHelper.setText(toEmail.getContent(),true);
        LocalDateTime now = LocalDateTime.now();
        try {
            if (file != null && file.exists()) {
                FileSystemResource fsr = new FileSystemResource(file);
                String filename = fsr.getFilename();
                //添加附件
                mimeMessageHelper.addAttachment(filename, fsr);
            }
            javaMailSender.send(message);
           // 记录发送成功的日志
        } catch (MailException e) {
            log.error("邮件发送异常:{}",e.getMessage());
            e.printStackTrace();
        }
        return R.success();
    }

通过字节数组流的方式发送,好处时不会产生临时文件,没有产生垃圾文件的烦恼

// fileName,
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
IoUtil.write(outputStream,false,ExcelExportUtils.getExcelBytes(fileName, summaryList, TransClassUtil.getTransClassBean(ReportSupplierRatingSummary.class)));

// 封装发邮件的参数
ToEmail toEmail = new ToEmail();
if (StrUtil.isEmpty(targetEmail)) {
    toEmail.setTos(emails);
} else {
    toEmail.setTos(targetEmail.split(","));
}
toEmail.setAlertColor(configuration.getAlertColor());
toEmail.setContent(content);
toEmail.setSubject(emailSubject);
try {
    sendEmailFile(toEmail,fileName,outputStream);
} catch (Exception e) {
    e.printStackTrace();
    log.error(e.getMessage());
}

@SneakyThrows
    @Override
    public R<?> sendEmailFile(ToEmail toEmail, String filename, ByteArrayOutputStream outputStream) throws MessagingException {
        MimeMessage message = javaMailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(message,true);
        mimeMessageHelper.setFrom(emailUsername);
        mimeMessageHelper.setTo(toEmail.getTos());
        mimeMessageHelper.setSubject(toEmail.getSubject());
        mimeMessageHelper.setText(toEmail.getContent(),true);
        LocalDateTime now = LocalDateTime.now();
        try {
            if (outputStream != null) {
                mimeMessageHelper.addAttachment(filename, ()-> new ByteArrayInputStream(outputStream.toByteArray()));
            }
            javaMailSender.send(message);
          // 记录发送成功日志
        } catch (MailException e) {
            log.error("邮件发送异常:{}",e.getMessage());
            e.printStackTrace();
        }
        return R.success();
    }
/**
     * 通过对象模板导出Excel
     */
    public static < T > byte[] getExcelBytes( String fileName, List< T > list, Class< ? > clazz ) {
        return getExcelBytes( fileName, list, clazz, true, null );
    }

    /**
     * 通过对象模板导出Excel
     */
    public static < T > byte[] getExcelBytes( String fileName, List< T > list, Class< ? > clazz, boolean distinct, List< ExcelHeader > excelHeaders ) {
        // 如果 list 为空,则导出模板数据
        if ( CollectionUtil.isEmpty( list ) ) {
            return getTemplateBytes( fileName, clazz, true, distinct, excelHeaders );
        }
        clazz = list.get( 0 ).getClass();
        // 获取表头字段
        List< ExcelField > excelFields = getExcelFields( clazz, distinct, excelHeaders );
        ExcelStyleDefinition styleDefinition = new ExcelStyleDefinition();
        styleDefinition.setExcelStyle( clazz.getAnnotation( ExcelStyle.class ) );
        List< Object > headNames = new ArrayList<>();
        for ( int i = 0; i < excelFields.size(); i++ ) {
            ExcelField each = excelFields.get( i );
            styleDefinition.getHeaderStyleMap().put( i, each.getExcelHeaderStyle() );
            styleDefinition.getRowStyleMap().put( i, each.getExcelRowStyle() );
            styleDefinition.getHexColorMap().put( i, each.isHexColor() );
            styleDefinition.getRequireMap().put( i, each.isRequire() );
            headNames.add( each.getName() );
        }
        List< List< Object > > sheetData = getSheetData( excelFields, list );
        sheetData.add( 0, headNames );

        // 导出数据
        ExcelDefinition excelDefinition = new ExcelDefinition();
        excelDefinition.setStyleDefinition( styleDefinition );

        Map< String, List< List< Object > > > sheetMap = new HashMap<>();
        sheetMap.put( fileName, sheetData );
        excelDefinition.setSheetMap( sheetMap );
        excelDefinition.setFileName( fileName );
        return exportExcel( excelDefinition );
    }
@SneakyThrows
    private static byte[] exportExcel( ExcelDefinition excelDefinition ) {
        XSSFWorkbook book = ( XSSFWorkbook ) WorkbookFactory.create( true );
        Set< Map.Entry< String, List< List< Object > > > > entries = excelDefinition.getSheetMap().entrySet();
        for ( Map.Entry< String, List< List< Object > > > entry : entries ) {
            List< List< Object > > sheetDataList = entry.getValue();
            XSSFSheet sheet = book.createSheet( entry.getKey() );
            ExcelStyleDefinition styleDefinition = excelDefinition.getStyleDefinition();
            renderSheetStyle( book, sheet, styleDefinition.getExcelStyle() );
            int rowLength = sheetDataList.size();
            int columnLength = sheetDataList.get( 0 ).size();
            int[][] mergeArray = new int[rowLength][columnLength];
            ExcelStyle excelStyle = styleDefinition.getExcelStyle();
            Map< Integer, XSSFCellStyle > cellStyleMap = new HashMap<>();
            Map< String, XSSFCellStyle > hexColorCellStyleMap = new HashMap<>();
            boolean init = true;
            for ( int i = 0; i < sheetDataList.size(); i++ ) {
                Row row = sheet.createRow( i );
                List< Object > rowList = sheetDataList.get( i );
                for ( int j = 0; j < rowList.size(); j++ ) {
                    Object o = rowList.get( j );
                    int v = 0;
                    Cell cell = row.createCell( j );
                    if ( i == 0 ) {
                        ExcelHeaderStyle headerStyle = styleDefinition.getHeaderStyleMap().get( j );
                        v = setCellValue( cell, o, renderRowStyle( book, excelStyle, headerStyle, null, false, styleDefinition.getRequireMap().get( j ) ) );
                        int width = 15;
                        if ( ObjectUtil.isNotNull( headerStyle ) ) {
                            width = headerStyle.width() == 0 ? ( ObjectUtil.isNotNull( excelStyle ) ? excelStyle.width() : width ) : headerStyle.width();
                        } else if ( ObjectUtil.isNotNull( excelStyle ) ) {
                            width = excelStyle.width();
                        }
                        sheet.setColumnWidth( j, width * 256 );
                    } else {
                        Boolean hexColor = styleDefinition.getHexColorMap().get( j );
                        if ( Optional.ofNullable( hexColor ).orElse( false ) ) {
                            if ( o != null ){
                                String hexColorStr = o.toString();
                                final int finalJ = j;
                                XSSFCellStyle style = hexColorCellStyleMap.computeIfAbsent( hexColorStr, color -> renderRowStyle( book, excelStyle, styleDefinition.getRowStyleMap().get( finalJ ), color, true, null ) );
                                v = setCellValue( cell, o, style );
                            }
                        } else {
                            if ( init && !cellStyleMap.containsKey( j ) ) {
                                cellStyleMap.put( j, renderRowStyle( book, excelStyle, styleDefinition.getRowStyleMap().get( j ), o, hexColor, null ) );
                            }
                            v = setCellValue( cell, o, cellStyleMap.get( j ) );
                        }
                    }
                    mergeArray[i][j] = v;
                }
                if ( i > 0 ) {
                    init = false;
                }
            }
            mergeCells( sheet, mergeArray );
        }
        // 写数据
        return getBytes( book );
    }

private static void mergeCells( Sheet sheet, int[][] mergeArray ) {
        for ( int x = 0; x < mergeArray.length; x++ ) {
            int[] arr = mergeArray[x];
            boolean merge = false;
            int y1 = 0;
            int y2 = 0;
            for ( int y = 0; y < arr.length; y++ ) {
                int value = arr[y];
                if ( value == CELL_COLUMN_MERGE ) {
                    if ( !merge ) {
                        y1 = y;
                    }
                    y2 = y;
                    merge = true;
                } else {
                    merge = false;
                    if ( y1 > 0 ) {
                        sheet.addMergedRegion( new CellRangeAddress( x, x, ( y1 - 1 ), y2 ) );
                    }
                    y1 = 0;
                    y2 = 0;
                }
            }
            if ( y1 > 0 ) {
                sheet.addMergedRegion( new CellRangeAddress( x, x, ( y1 - 1 ), y2 ) );
            }
        }
        int xLen = mergeArray.length;
        int yLen = mergeArray[0].length;
        for ( int y = 0; y < yLen; y++ ) {
            boolean merge = false;
            int x1 = 0;
            int x2 = 0;
            for ( int x = 0; x < xLen; x++ ) {
                int value = mergeArray[x][y];
                if ( value == CELL_ROW_MERGE ) {
                    if ( !merge ) {
                        x1 = x;
                    }
                    x2 = x;
                    merge = true;
                } else {
                    merge = false;
                    if ( x1 > 0 ) {
                        sheet.addMergedRegion( new CellRangeAddress( ( x1 - 1 ), x2, y, y ) );
                    }
                    x1 = 0;
                    x2 = 0;
                }
            }
            if ( x1 > 0 ) {
                sheet.addMergedRegion( new CellRangeAddress( ( x1 - 1 ), x2, y, y ) );
            }
        }
    }

private static int setCellValue( Cell cell, Object o, XSSFCellStyle style ) {
cell.setCellStyle( style );
if ( ObjectUtil.isNull( o ) ) {
    cell.setCellType( CellType.STRING );
    cell.setCellValue( "" );
    return CELL_OTHER;
}
// 是否为字符串
if ( o instanceof String || isNumeric( o ) ) {
    String s = o.toString();
    // 当数字类型长度超过8位时,改为字符串类型显示(Excel数字超过一定长度会显示为科学计数法)
    if ( isNumeric( o ) && s.length() < 8 ) {
	cell.setCellType( CellType.NUMERIC );
	cell.setCellValue( Double.parseDouble( s ) );
	return CELL_OTHER;
    } else {
	cell.setCellType( CellType.STRING );
	cell.setCellValue( s );
    }
    if ( s.equals( ROW_MERGE ) ) {
	return CELL_ROW_MERGE;
    } else if ( s.equals( COLUMN_MERGE ) ) {
	return CELL_COLUMN_MERGE;
    } else {
	return CELL_OTHER;
    }
}

if ( o instanceof Boolean ) {
    cell.setCellType( CellType.BOOLEAN );
    cell.setCellValue( ( Boolean ) o );
    return CELL_OTHER;
}
if ( o instanceof BigDecimal ) {
    cell.setCellType( CellType.NUMERIC );
    cell.setCellValue( ( ( BigDecimal ) o ).setScale( 3, RoundingMode.HALF_UP ).doubleValue() );
    return CELL_OTHER;
}
if ( o instanceof Date ) {
    cell.setCellType( CellType.STRING );
    cell.setCellValue( DateUtil.format( ( Date ) o, DatePattern.NORM_DATE_PATTERN ) );
    return CELL_OTHER;
}
if ( o instanceof LocalDate ) {
    cell.setCellType( CellType.STRING );
    cell.setCellValue( LocalDateTimeUtil.format( ( LocalDate ) o, DatePattern.NORM_DATE_PATTERN ) );
    return CELL_OTHER;
}
if ( o instanceof LocalDateTime ) {
    cell.setCellType( CellType.STRING );
    cell.setCellValue( LocalDateTimeUtil.format( ( LocalDateTime ) o, DatePattern.NORM_DATETIME_PATTERN ) );
    return CELL_OTHER;
}
cell.setCellType( CellType.STRING );
cell.setCellValue( o.toString() );
return CELL_OTHER;
}

private static XSSFCellStyle renderRowStyle( XSSFWorkbook workbook, ExcelStyle excelStyle, Annotation style, Object o, Boolean hexColor, Boolean require ) {
        if ( ObjectUtil.isNull( workbook ) ) {
            return null;
        }
        XSSFFont font = workbook.createFont();
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        boolean styleNotNull = ObjectUtil.isNotNull( excelStyle );
        if ( styleNotNull ) {
            font.setBold( excelStyle.bold() );
            cellStyle.setWrapText( excelStyle.wrap() );
        }

        if ( ObjectUtil.isNotNull( style ) ) {
            ExcelRowStyle rowStyle;
            if ( style instanceof ExcelRowStyle ) {
                rowStyle = ( ExcelRowStyle ) style;
            } else {
                ExcelHeaderStyle headerStyle = ( ExcelHeaderStyle ) style;
                rowStyle = headerStyle.rowStyle();
            }
            int bold = rowStyle.bold();
            font.setBold( bold == 0 ? ( styleNotNull && excelStyle.bold() ) : bold > 0 );
            font.setColor( rowStyle.color().index );
            int wrap = rowStyle.wrap();
            cellStyle.setWrapText( wrap == 0 ? ( styleNotNull && excelStyle.wrap() ) : wrap > 0 );
            cellStyle.setAlignment( rowStyle.horizontalAlign() );
            cellStyle.setVerticalAlignment( rowStyle.verticalAlign() );
            cellStyle.setFillForegroundColor( rowStyle.backgroundColor().index );
            cellStyle.setFillPattern( FillPatternType.SOLID_FOREGROUND );
        } else {
            cellStyle.setAlignment( HorizontalAlignment.CENTER );
            cellStyle.setVerticalAlignment( VerticalAlignment.CENTER );
        }
        if ( require != null && require ) {
            XSSFColor fontColor = new XSSFColor();
            fontColor.setARGBHex( "FF0000" );
            font.setColor( fontColor );
        }
        cellStyle.setFont( font );
        if ( styleNotNull && excelStyle.border() ) {
            cellStyle.setBorderTop( BorderStyle.THIN );
            cellStyle.setTopBorderColor( IndexedColors.BLACK.index );
            cellStyle.setBorderRight( BorderStyle.THIN );
            cellStyle.setRightBorderColor( IndexedColors.BLACK.index );
            cellStyle.setBorderBottom( BorderStyle.THIN );
            cellStyle.setBottomBorderColor( IndexedColors.BLACK.index );
            cellStyle.setBorderLeft( BorderStyle.THIN );
            cellStyle.setLeftBorderColor( IndexedColors.BLACK.index );
        }
        if ( hexColor != null && hexColor && o != null ) {
            String hexColorStr = o.toString();
            XSSFColor xssfColor = new XSSFColor();
            if ( hexColorStr.startsWith( "#" ) ) {
                hexColorStr = hexColorStr.substring( 1 );
            }
            if ( hexColorStr.length() == 6 || hexColorStr.length() == 8 ) {
                xssfColor.setARGBHex( hexColorStr );
                cellStyle.setFillForegroundColor( xssfColor );
                cellStyle.setFillBackgroundColor( xssfColor );
                cellStyle.setFillPattern( FillPatternType.SOLID_FOREGROUND );
                font.setColor( xssfColor );
            }
        }
        return cellStyle;
    }
 @SneakyThrows
    private static byte[] getBytes( XSSFWorkbook book ) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        book.write( bos );
        return bos.toByteArray();
    }

生成excel部分可以按照自己的想法实现,上面缺少部分自定义注解实现部分,照着poi或者easyexcel的示例都可以将表中读取的内容写入excel

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

sqlserver设置定时任务计划(SSMS)

软件&#xff1a;SQL Server Management Studio&#xff08;SSMS&#xff09; 1.连接数据库服务器&#xff0c;找到 SQL Sever Agent&#xff08;代理&#xff09; 启动 2.启动后&#xff0c;点开 Jobs&#xff08;作业&#xff09; 新建&#xff0c;填写常规信息 3.步骤 > …

如何规范的提交Git?

多人协作开发提交代码通常是遵循约定式提交规范&#xff0c;如果严格安照约定式提交规范&#xff0c; 手动进行代码提交的话&#xff0c;那么是一件非常痛苦的事情&#xff0c;但是 Git 提交规范的处理又势在必行&#xff0c;那么怎么办呢&#xff1f; 经过了很多人的冥思苦想…

WPF编程excel表格操作

WPF编程excel表格操作 摘要NPOI安装封装代码测试代码 摘要 Excel操作几种方式 使用开源库NPOI(常用&#xff0c;操作丰富)使用Microsoft.Office.Interop.Excel COM组件(兼容性问题)使用OpenXml(效率高)使用OleDb(过时) NPOI安装 封装代码 using System; using System.IO; u…

初识 Conda:一站式包管理和环境管理工具

文章目录 1. 什么是 Conda&#xff1f;2. 为什么选择 Conda&#xff1f;3. Conda 的安装3.1 安装步骤&#xff08;以 Miniconda 为例&#xff09; 4. Conda 的核心功能4.1 包管理4.2 环境管理4.3 Conda Forge4.4 设置国内镜像 5. 常见使用场景5.1 数据科学项目5.2 离线安装5.3 …

docker 搭建集群

准备3台机器&#xff1a; #dockermaster 192.168.31.150 sudo hostnamectl set-hostname dockermaster #初始化主节点 docker swarm init --advertise-addr 192.168.31.150 #查看集群是否搭建成功 docker node ls #dockernode1 192.168.31.151 sudo hostnamectl set-hostname …

Kafka消息不丢失与重复消费问题解决方案总结

1. 生产者层面 异步发送与回调处理 异步发送方式&#xff1a;生产者一般使用异步方式发送消息&#xff0c;异步发送有消息和回调接口两个参数。在回调接口的重写方法中&#xff0c;可通过异常参数判断消息发送状态。若消息发送成功&#xff0c;异常参数为null&#xff1b;若发…

StarRocks 存算分离在得物的降本增效实践

编者荐语&#xff1a; 得物优化数据引擎布局&#xff0c;近期将 4000 核 ClickHouse 迁移至自建 StarRocks&#xff0c;成本降低 40%&#xff0c;查询耗时减半&#xff0c;集群稳定性显著提升。本文详解迁移实践与成果&#xff0c;文末附丁凯剑老师 StarRocks Summit Asia 2024…

微服务-1 认识微服务

目录​​​​​​​ 1 认识微服务 1.1 单体架构 1.2 微服务 1.3 SpringCloud 2 服务拆分原则 2.1 什么时候拆 2.2 怎么拆 2.3 服务调用 3. 服务注册与发现 3.1 注册中心原理 3.2 Nacos注册中心 3.3 服务注册 3.3.1 添加依赖 3.3.2 配置Nacos 3.3.3 启动服务实例 …

IDEA工具使用介绍、IDEA常用设置以及如何集成Git版本控制工具

文章目录 一、IDEA二、建立第一个 Java 程序三、IDEA 常用设置四、IDEA 集成版本控制工具&#xff08;Git、GitHub&#xff09;4.1 IDEA 拉 GitHub/Git 项目4.2 IDEA 上传 项目到 Git4.3 更新提交命令 一、IDEA 1、什么是IDEA&#xff1f; IDEA&#xff0c;全称为 IntelliJ ID…

kafka开机自启失败问题处理

前言&#xff1a;在当今大数据处理领域&#xff0c;Kafka 作为一款高性能、分布式的消息队列系统&#xff0c;发挥着举足轻重的作用。无论是海量数据的实时传输&#xff0c;还是复杂系统间的解耦通信&#xff0c;Kafka 都能轻松应对。然而&#xff0c;在实际部署和运维 Kafka 的…

二维数组综合

第1题 稀疏矩阵 查看测评数据信息 nm矩阵大部分元素是0的矩阵称为稀疏矩阵&#xff0c;假设有k个非0元素&#xff0c;则可把稀疏矩阵用K3的矩阵简记之&#xff0c;其中第一列是行号&#xff0c;第二列是列号&#xff0c;第三列是该行、该列下的非0元素的值。如&#xff1a;…

STM32-笔记20-测量按键按下时间

1、按键按下的时间-思路 我们先检测下降沿信号&#xff0c;检测到以后&#xff0c;在回调函数里切换成检测上升沿信号&#xff0c;当两个信号都检测到的时候&#xff0c;这段时间就是按键按下的时间&#xff0c;如图所示&#xff1a;>N*(ARR1)CCRx的值 N是在这段时间内&…

【网络协议】路由信息协议 (RIP)

未经许可&#xff0c;不得转载。 路由信息协议&#xff08;Routing Information Protocol&#xff0c;简称 RIP&#xff09;是一种使用跳数&#xff08;hop count&#xff09;作为路由度量标准的路由协议&#xff0c;用于确定源网络和目标网络之间的最佳路径。 文章目录 什么是…

PHP后执行php.exe -v命令报错并给出解决方案

文章目录 一、执行php.exe -v命令报错解决方案 一、执行php.exe -v命令报错 -PHP Warning: ‘C:\windows\SYSTEM32\VCRUNTIME140.dll’ 14.38 is not compatible with this PHP build linked with 14.41 in Unknown on line 0 解决方案 当使用PHP8.4.1时遇到VCRUNTIME140.dll…

blender中合并的模型,在threejs中显示多个mesh;blender多材质烘培成一个材质

描述&#xff1a;在blender中合并的模型导出为glb&#xff0c;在threejs中导入仍显示多个mesh&#xff0c;并不是统一的整体&#xff0c;导致需要整体高亮或者使用DragControls等不能统一控制。 原因&#xff1a;模型有多个材质&#xff0c;在blender中合并的时候&#xff0c;…

0xc0000020错误代码怎么处理,Windows11、10坏图像错误0xc0000020的修复办法

“0xc0000020”是一种 Windows 应用程序错误代码&#xff0c;通常表明某些文件缺失或损坏。这可能是由于系统文件损坏、应用程序安装或卸载问题、恶意软件感染、有问题的 Windows 更新等原因导致的。 比如&#xff0c;当运行软件时&#xff0c;可能会出现类似“C:\xx\xxx.dll …

wangEditor富文本插件在vue项目中使用和媒体上传的实现

wangEditor是前端一个比较流行的简洁易用&#xff0c;功能强大的前端富文本编辑器&#xff0c;支持 JS Vue React&#xff0c;提供了很多丰富的功能&#xff0c;下面手把手教你实现wangWditor富文本插件在vue项目中配置&#xff0c;保存、图片上传等功能。无脑ctrlc即可 基本功…

MySQL root用户密码忘记怎么办(Reset root account password)

在使用MySQL数据库的的过程中&#xff0c;不可避免的会出现忘记密码的现象。普通用户的密码如果忘记&#xff0c;可以用更高权限的用户&#xff08;例如root&#xff09;进行重置。但是如果root用户的密码忘记了&#xff0c;由于root用户本身就是最高权限&#xff0c;那这个方法…

C语言学习笔记(1)

在学习前&#xff0c;需要有一定的C语言基础。不必很深入&#xff0c;只需要知道函数&#xff0c;头文件&#xff0c;指针&#xff0c;数组等的概念就可以&#xff0c;但并非0基础笔记。 由于写到后面&#xff0c;不好编辑了&#xff0c;决定分成多篇写&#xff0c;请按编号学…

使用uWSGI将Flask应用部署到生产环境

使用uWSGI将Flask应用部署到生产环境&#xff1a; 1、安装uWSGI conda install -c conda-forge uwsgi&#xff08;pip install uwsgi会报错&#xff09; 2、配置uWSGI 在python程序的同一文件夹下创建 uwsgi.ini文件&#xff0c;文件内容如下表。 需要按照实际情况修改文件名称…