C#通过NPOI 读、写Excel数据;合并单元格、简单样式修改;通过读取已有的Excel模板另存为文件

文章目录

  • 1 需要引用的DLL
  • 2 调用示例
  • 3 工具类

1 需要引用的DLL

在这里插入图片描述

2 调用示例

public static void WriteExcel()
{
    string templateFile = @"F:\12312\excel.xlsx"; // 文件必须存在
    string outFile = @"F:\12312\" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".xlsx";
    string picPath = @"F:\12312\test.jpg";

    IWorkbook workbook = ExcelHelper.GetReadWorkbook(templateFile);

    ISheet sheet = workbook.GetSheetAt(0);

    try
    {
        ExcelHelper.SetCellValue(sheet, 20, 0, "这里是第1行第1列内容");
        ExcelHelper.SetCellValue(sheet, 0, 1, "这里是第1行第2列内容");

        ExcelHelper.SetCellValue(sheet, 1, 0, "这里是第2行第1列内容");
        ExcelHelper.SetCellValue(sheet, 1, 1, "这里是第2行第2列内容");

        // Height:单位是1/20个点,所以要想得到一个点的话,需要乘以20。
        sheet.GetRow(1).Height = 44 * 20; // 给第2行设置行高

        // Width: 单位是1/256个字符宽度,所以要乘以256才是一整个字符宽度
        sheet.SetColumnWidth(1, 50 * 256); // 给第1列设置宽度

        ExcelHelper.SetCellValue(sheet, 2, 0, "这里是第3行第1列内容,需要设置字体样式");

        // 从第3行到第6行,第1列到第4列合并单元格
        ExcelHelper.SetCellRangeAddress(sheet, 2, 5, 0, 3);

        // 给合并之后的单元格加边框,并设置字体大小、居中、字体颜色、背景色
        ExcelHelper.AddRengionBorder(workbook, sheet, 2, 5, 0, 3);

        // 插入图片
        var bitmap = (Bitmap)Image.FromFile("1.bmp");
        ExcelHelper.InsertImage(workbook, sheet, 7, 16, 0, 2, bitmap);

        ExcelHelper.Save(workbook, outFile);

        Process.Start(outFile);

    }
    catch (Exception ex)
    {
        throw ex;
    }
}

3 工具类

using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;


namespace Demo_Excel
{
    /// <summary>
    /// Excel导入导出帮助类--通过插件NPOI来实现导入导出操作
    /// 常见异常:
    /// 1.未添加ICSharpCode.SharpZipLib.dll
    /// </summary>
    public class ExcelHelper
    {
        /// <summary>
        /// 获取读取文件的IWorkbook对象
        /// </summary>
        /// <param name="filename">文件路径</param>
        /// <returns></returns>
        public static IWorkbook GetReadWorkbook(string filename)
        {
            FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            IWorkbook workbook;

            string fileExt = Path.GetExtension(filename).ToLower();
            switch (fileExt)
            {
                case ".xlsx":
                    workbook = new XSSFWorkbook(fs);
                    break;
                case ".xls":
                    workbook = new HSSFWorkbook(fs);
                    break;
                default:
                    throw new Exception("不支持的文件类型");
            }
            fs.Close();
            return workbook;
        }

        /// <summary>
        /// 获取读取文件的IWorkbook对象
        /// </summary>
        /// <param name="filename">文件路径</param>
        /// <returns></returns>
        public static IWorkbook GetWriteWorkbook(string filename)
        {
            if (string.IsNullOrWhiteSpace(filename))
                throw new Exception("不支持的文件类型");

            string fileExt = Path.GetExtension(filename).ToLower();

            switch (fileExt)
            {
                case ".xlsx": return new XSSFWorkbook();
                case ".xls": return new HSSFWorkbook();
                default: throw new Exception("不支持的文件类型");
            }
        }

        public static void Save(IWorkbook workbook, string filename)
        {
            MemoryStream stream = new MemoryStream();
            workbook.Write(stream);
            var buf = stream.ToArray();

            //保存文件  
            using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write))
            {
                fs.Write(buf, 0, buf.Length);
                fs.Flush();
                fs.Close();
            }
        }

        /// <summary>
        /// 根据Excel模板更新Excel数据
        /// </summary>
        /// <param name="sourcefile">模板文件的路径</param>
        /// <param name="outfile">输出文件的内容</param>
        /// <param name="sheetIndex">模板文件在sheet中的编号</param>
        /// <param name="dictionary">用于更新数据的键值对,key:模板中需要录入信息的标识;Value:录入信息的内容</param>
        /// <returns></returns>
        public static int UpdataExcel(string sourcefile, string outfile, int sheetIndex, Dictionary<string, string> dictionary)
        {

            var allKeys = dictionary.Keys.ToArray();

            IWorkbook workbook = GetReadWorkbook(sourcefile);

            ISheet sheet = workbook.GetSheetAt(sheetIndex);

            int endRow = sheet.LastRowNum;
            for (int i = 0; i < endRow; i++)
            {
                var row = sheet.GetRow(i);
                for (int j = 0; j < row.LastCellNum; j++)
                {
                    var data = GetCellString(row.GetCell(j));
                    if (allKeys.Contains(data))
                    {
                        row.Cells[j].SetCellValue(dictionary[data]);
                    }
                }
            }

            Save(workbook, outfile);

            return 0;
        }

        /// <summary>
        /// 根据Excel模板更新Excel数据
        /// </summary>
        /// <param name="sourcefile">模板文件的路径</param>
        /// <param name="outfile">输出文件的内容</param>
        /// <param name="sheetIndex">模板文件在sheet中的编号</param>
        /// <param name="dictionary">用于更新数据的键值对,key:模板中需要录入信息的单元格的位置,X:行,Y:列;Value:录入信息的内容</param>
        /// <returns></returns>
        public static int UpdataExcel(string sourcefile, string outfile, int sheetIndex, Dictionary<Point, string> dictionary)
        {

            IWorkbook workbook = GetReadWorkbook(sourcefile);

            ISheet sheet = workbook.GetSheetAt(sheetIndex);

            foreach (var key in dictionary.Keys)
            {
                SetCellValue(sheet, key.X, key.Y, dictionary[key]);
            }

            Save(workbook, outfile);

            return 0;
        }

        /// <summary>
        /// 将DataTable数据导入到excel中
        /// </summary>
        /// <param name="fileName">文件路径</param>
        /// <param name="data">要导入的数据</param>
        /// <param name="sheetName">要导入的excel的sheet的名称</param>
        /// <param name="isColumnWritten">DataTable的列名是否要导入</param>
        /// <returns>导入数据行数(包含列名那一行)</returns>
        public static int Write(string fileName, DataTable data, string sheetName, bool isColumnWritten)
        {
            try
            {
                IWorkbook workbook = GetWriteWorkbook(fileName);

                ISheet sheet = workbook.CreateSheet(sheetName);

                int count = 0;//写入数据行

                if (isColumnWritten)
                {
                    //读取标题  
                    IRow rowHeader = sheet.CreateRow(count++);
                    for (int i = 0; i < data.Columns.Count; i++)
                    {
                        ICell cell = rowHeader.CreateCell(i);
                        cell.SetCellValue(data.Columns[i].ColumnName);
                    }
                }

                //读取数据  
                for (int i = 0; i < data.Rows.Count; i++)
                {
                    IRow rowData = sheet.CreateRow(count++);
                    for (int j = 0; j < data.Columns.Count; j++)
                    {
                        ICell cell = rowData.CreateCell(j);
                        cell.SetCellValue(data.Rows[i][j].ToString());
                    }
                }

                Save(workbook, fileName);

                return count;
            }
            catch (Exception ex)
            {
                return -1;
            }
        }

        /// <summary>
        /// 将DataTable数据导入到excel中
        /// </summary>
        /// <param name="fileName">文件路径</param>
        /// <param name="data">要导入的数据</param>
        /// <param name="isColumnWritten">DataTable的列名是否要导入</param>
        /// <returns>导入数据行数(包含列名那一行)</returns>
        public static int Write(string fileName, DataTable data, bool isColumnWritten)
        {
            int ret = Write(fileName, data, "Sheet1", isColumnWritten);
            return ret;
        }

        /// <summary>
        /// 将DataTable数据导入到excel中(包含列名,工作簿名称为:Sheet1)
        /// </summary>
        /// <param name="fileName">文件路径</param>
        /// <param name="data">要导入的数据</param>
        /// <returns>导入数据行数(包含列名那一行)</returns>
        public static int Write(string fileName, DataTable data)
        {
            int ret = Write(fileName, data, true);
            return ret;
        }

        /// <summary>
        /// 读取Excel数据到DataTable
        /// </summary>
        /// <param name="fileName">文件名称</param>
        /// <param name="sheetIndex">sheet索引</param>
        /// <param name="isFirstRowCellName">第一行数据是否为列名</param>
        /// <param name="data">存储读取的数据</param>
        /// <returns></returns>
        public static int Read(string fileName, int sheetIndex, bool isFirstRowCellName, out DataTable data)
        {
            data = new DataTable();
            try
            {
                IWorkbook workbook = GetReadWorkbook(fileName);

                ISheet sheet = workbook.GetSheetAt(sheetIndex);

                if (isFirstRowCellName)
                {
                    IRow firstRow = sheet.GetRow(0);
                    var list = ReadDataRow(firstRow);
                    data.Columns.AddRange(list.Select(t => new DataColumn(t)).ToArray());
                }
                else
                {
                    int nMaxCol = 0;
                    for (int i = 0; i < sheet.LastRowNum; i++)
                    {
                        nMaxCol = Math.Max(nMaxCol, sheet.GetRow(i).LastCellNum);
                    }
                    for (int i = 0; i < nMaxCol; i++)
                    {
                        data.Columns.Add($"列{i + 1}");
                    }
                }

                int startRow = !isFirstRowCellName ? 0 : 1;
                int endRow = sheet.LastRowNum;
                var ret2 = Read(sheet, startRow, endRow, ref data);

                if (ret2 < 0) return -1;

                return data.Rows.Count;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 读取Excel数据到DataTable
        /// </summary>
        /// <param name="fileName">文件名称</param>
        /// <param name="sheetName">sheet名称</param>
        /// <param name="isFirstRowCellName">第一行数据是否为列名</param>
        /// <param name="data">存储读取的数据</param>
        /// <returns></returns>
        public static int Read(string fileName, string sheetName, bool isFirstRowCellName, out DataTable data)
        {
            data = new DataTable();
            try
            {

                IWorkbook workbook = GetReadWorkbook(fileName);

                ISheet sheet = workbook.GetSheet(sheetName);
                Console.WriteLine(sheet.SheetName);
                if (isFirstRowCellName)
                {
                    IRow firstRow = sheet.GetRow(0);
                    var list = ReadDataRow(firstRow);
                    data.Columns.AddRange(list.Select(t => new DataColumn(t)).ToArray());
                }
                else
                {
                    int nMaxCol = 0;
                    for (int i = 0; i < sheet.LastRowNum; i++)
                    {
                        nMaxCol = Math.Max(nMaxCol, sheet.GetRow(i).LastCellNum);
                    }
                    for (int i = 0; i < nMaxCol; i++)
                    {
                        data.Columns.Add($"列{i + 1}");
                    }
                }

                int startRow = !isFirstRowCellName ? 0 : 1;
                int endRow = !isFirstRowCellName ? 0 : 1;
                var ret = Read(sheet, startRow, endRow, ref data);
                if (ret < 0)
                    return -1;

                return data.Rows.Count;
            }
            catch (Exception ex)
            {

                return -1;
            }
        }

        /// <summary>
        /// 读取Excel数据到DataTable
        /// </summary>
        /// <param name="fileName">文件名称</param>
        /// <param name="isFirstRowCellName">第一行数据是否为列名</param>
        /// <param name="data">存储读取的数据</param>
        /// <returns></returns>
        public static int Read(string fileName, bool isFirstRowCellName, out DataTable data)
        {
            int ret = Read(fileName, "sheet1", isFirstRowCellName, out data);
            return ret;
        }

        /// <summary>
        /// 读取Excel数据到DataTable
        /// </summary>
        /// <param name="fileName">文件名称</param>
        /// <param name="data">存储读取的数据</param>
        /// <returns></returns>
        public static int Read(string fileName, out DataTable data)
        {
            int ret = Read(fileName, "sheet1", false, out data);
            return ret;
        }

        /// <summary>
        /// 从指定行开始读取所有sheet的数据到DataTable(DataTable列名已创建)
        /// </summary>
        /// <param name="sheet">工作簿</param>
        /// <param name="startRow">指定读取起始行</param>
        /// <param name="endRow">指定读取结束行</param>
        /// <param name="data">存储读取的数据</param>
        /// <returns></returns>
        public static int Read(ISheet sheet, int startRow, int endRow, ref DataTable data)
        {
            endRow += 1;
            for (int i = startRow; i < endRow; i++)
            {
                var sheetRow = sheet.GetRow(i);
                if (sheetRow == null)
                {
                    data.Rows.Add();
                }
                else
                {
                    var list = ReadDataRow(sheetRow);
                    var row = data.NewRow();

                    int count = Math.Min(list.Count, data.Columns.Count);
                    for (int j = 0; j < count; j++)
                    {
                        row[j] = list[j];
                    }
                    data.Rows.Add(row);
                }

            }
            return data.Rows.Count;
        }

        /// <summary>
        /// 读取数据行
        /// </summary>
        /// <param name="sheet"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static List<string> ReadDataRow(ISheet sheet, int index) => ReadDataRow(sheet.GetRow(index));

        /// <summary>
        /// 读取数据行
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        public static List<string> ReadDataRow(IRow row)
        {
            List<string> result = null;
            if (row != null)
            {
                result = new List<string>();
                int startColumn = 0;
                int endColumn = row.LastCellNum;
                for (int i = startColumn; i < endColumn; i++)
                {
                    result.Add(GetCellString(row.GetCell(i)));
                }
            }
            return result;
        }
        
        /// <summary>
        /// 往EXCEL指定单元格插入图片
        /// </summary>
        /// <param name="workbook"></param>
        /// <param name="sheet"></param>
        /// <param name="firstRow"> 起始单元格行序号,从0开始计算</param>
        /// <param name="lastRow">  终止单元格行序号,从0开始计算</param>
        /// <param name="firstCell"> 起始单元格列序号,从0开始计算</param>
        /// <param name="lastCell">  终止单元格列序号,从0开始计算</param>
        /// <param name="bitmap">插入的图片</param> 
        public static void InsertImage(IWorkbook workbook, ISheet sheet, int firstRow, int lastRow, int firstCell, int lastCell, Bitmap bitmap)
        {
            // 将图片转换为字节数组
            byte[] imgBytes = BitmapToBytes(bitmap);

            int pictureIdx = workbook.AddPicture(imgBytes, PictureType.PNG);

            if (workbook is XSSFWorkbook)
            {
                XSSFDrawing patriarch = (XSSFDrawing)sheet.CreateDrawingPatriarch();

                // dx1:起始单元格的x偏移量,如例子中的255表示直线起始位置距A1单元格左侧的距离;
                // dy1:起始单元格的y偏移量,如例子中的125表示直线起始位置距A1单元格上侧的距离;
                // dx2:终止单元格的x偏移量,如例子中的1023表示直线起始位置距C3单元格左侧的距离;
                // dy2:终止单元格的y偏移量,如例子中的150表示直线起始位置距C3单元格上侧的距离;
                // col1:起始单元格列序号,从0开始计算;
                // row1:起始单元格行序号,从0开始计算,如例子中col1 = 0,row1 = 0就表示起始单元格为A1;
                // col2:终止单元格列序号,从0开始计算;
                // row2:终止单元格行序号,从0开始计算,如例子中col2 = 2,row2 = 2就表示起始单元格为C3;
                XSSFClientAnchor anchor = new XSSFClientAnchor(10, 10, 0, 0, firstCell, firstRow, lastCell, lastRow);

                //把图片插到相应的位置
                XSSFPicture pict = (XSSFPicture)patriarch.CreatePicture(anchor, pictureIdx);
            }
            else
            {
                HSSFPatriarch patriarch = (HSSFPatriarch)sheet.CreateDrawingPatriarch();
                HSSFClientAnchor anchor = new HSSFClientAnchor(10, 10, 0, 0, firstCell, firstRow, lastCell, lastRow);

                //把图片插到相应的位置
                HSSFPicture pict = (HSSFPicture)patriarch.CreatePicture(anchor, pictureIdx);
            }

        }

        /// <summary>
        /// 单元格设置内容
        /// </summary>
        /// <param name="sheet"></param>
        /// <param name="rowIndex">第几行,从0开始</param>
        /// <param name="cellIndex">第几列,从0开始</param>
        /// <param name="value">内容(字符串)</param>
        public static void SetCellValue(ISheet sheet, int rowIndex, int cellIndex, string value)
        {
            if (sheet.GetRow(rowIndex) == null)
            {
                sheet.CreateRow(rowIndex);
            }
            if (sheet.GetRow(rowIndex).GetCell(cellIndex) == null)
            {
                sheet.GetRow(rowIndex).CreateCell(cellIndex);
            }
            sheet.GetRow(rowIndex).GetCell(cellIndex).SetCellValue(value);
        }

        /// <summary>
        /// 合并单元格
        /// </summary>
        /// <param name="sheet">要合并单元格所在的sheet</param>
        /// <param name="rowstart">开始行的索引</param>
        /// <param name="rowend">结束行的索引</param>
        /// <param name="colstart">开始列的索引</param>
        /// <param name="colend">结束列的索引</param>
        public static void SetCellRangeAddress(ISheet sheet, int rowstart, int rowend, int colstart, int colend)
        {
            for (int r = rowstart; r <= rowend; r++)
            {
                for (int c = colstart; c <= colend; c++)
                {
                    if (sheet.GetRow(r) == null)
                    {
                        sheet.CreateRow(r); // 如果行不存在,则创建行
                    }
                    if (sheet.GetRow(r).GetCell(c) == null)
                    {
                        sheet.GetRow(r).CreateCell(c); // 如果列不存在,则创建列
                    }
                }
            }
            CellRangeAddress cellRangeAddress = new CellRangeAddress(rowstart, rowend, colstart, colend);
            sheet.AddMergedRegion(cellRangeAddress);
        }

        /// <summary>
        /// 加范围边框和设置字体大小、颜色、背景色、居中
        /// </summary>
        /// <param name="firstRow">起始行</param>
        /// <param name="lastRow">结束行</param>
        /// <param name="firstCell">起始列</param>
        /// <param name="lastCell">结束列</param>
        /// <returns></returns>
        public static void AddRengionBorder(IWorkbook workbook, ISheet sheet, int firstRow, int lastRow, int firstCell, int lastCell)
        {
            for (int i = firstRow; i < lastRow; i++)
            {
                for (int n = firstCell; n < lastCell; n++)
                {
                    ICell cell;
                    cell = sheet.GetRow(i).GetCell(n);
                    if (cell == null)
                    {
                        cell = sheet.GetRow(i).CreateCell(n);
                    }
                    ICellStyle style = sheet.Workbook.CreateCellStyle();
                    style.BorderTop = BorderStyle.Thin;
                    style.BorderBottom = BorderStyle.Thin;
                    style.BorderLeft = BorderStyle.Thin;
                    style.BorderRight = BorderStyle.Thin;
                    style.Alignment = HorizontalAlignment.Center;   //水平对齐 :居中
                    style.VerticalAlignment = VerticalAlignment.Center; //垂直对齐  :居中

                    if (i == firstRow) //第一行
                    {
                        style.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Black.Index; // 背景色:黑色
                        style.FillPattern = FillPattern.SolidForeground;

                        IFont font = workbook.CreateFont(); //创建一个字体颜色
                        font.Color = NPOI.HSSF.Util.HSSFColor.White.Index;  //字体颜色:白色      
                        font.FontHeightInPoints = 18;//字体大小       

                        style.SetFont(font); //给样式设置字体
                    }

                    cell.CellStyle = style;
                }

            }
        }

        /// <summary>
        /// Bitmap转换为字节数组
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        private static byte[] BitmapToBytes(Bitmap bitmap)
        {
            // 1.先将BitMap转成内存流
            MemoryStream ms = new MemoryStream();
            bitmap.Save(ms, ImageFormat.Bmp);
            ms.Seek(0, SeekOrigin.Begin);
            // 2.再将内存流转成byte[]并返回
            byte[] bytes = new byte[ms.Length];
            ms.Read(bytes, 0, bytes.Length);
            ms.Dispose();
            return bytes;
        }

        /// <summary>
        /// 获取单元格数据
        /// </summary>
        /// <param name="cell"></param>
        /// <returns></returns>
        private static string GetCellString(ICell cell)
        {
            if (cell != null)
            {
                switch (cell.CellType)
                {
                    case CellType.Unknown:
                        return "";
                    case CellType.Numeric:
                        return cell.NumericCellValue.ToString();
                    case CellType.String:
                        return cell.StringCellValue;
                    case CellType.Formula:
                        return cell.CellFormula;
                    case CellType.Blank:
                        return "";
                    case CellType.Boolean:
                        return cell.BooleanCellValue.ToString();
                    case CellType.Error:
                        return "";
                    default:
                        return "";
                }
            }
            else
            {
                return "";
            }
        }
    }

}

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

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

相关文章

2023年港澳台联考中录取分数高性价比的985和211大学来啦

导读 一直以来&#xff0c;985和211都是港澳台联考报名录取中&#xff0c;大家最关心的两类大学。其实每年的港澳台联考都有一些性价比很高的学校&#xff0c;今天我们就来看一下这些优秀的985和211大学吧&#xff01;&#xff08;景于行跟您承诺&#xff0c;本篇文章分享的分数…

医疗影像数据集—CT、X光、骨折、阿尔茨海默病MRI、肺部、肿瘤疾病等图像数据集

最近收集了一大波关于CT、X光等医疗方面的数据集包含骨折、阿尔茨海默病MRI、肺部疾病等类型的医疗影像数据&#xff0c;废话不多说&#xff0c;给大家逐一介绍&#xff01;&#xff01; 1、彩色预处理阿尔茨海默病MRI(磁共振成像)图像数据集 彩色预处理阿尔茨海默病MRI(磁共…

ERRO报错

无法下载nginx 如下解决&#xff1a; 查看是否有epel 源 安装epel源 安装第三方 yum -y install epel-release.noarch NGINX端口被占用 解决&#xff1a; 编译安装的NGINX配置文件在/usr/local/ngin/conf 修改端口

63 权限提升-Linux脏牛内核漏洞SUID信息收集

目录 演示案例:Linux提权自动化脚本利用-4个脚本Linux提权SUID配合脚本演示-AliyunLinux提权本地配合内核漏洞演示-MozheLinux提权脏牛内核漏洞演示-Aliyun&#xff0c;Vulnhub涉及资源: linux提权相对windows提权方法相对少一些&#xff0c;linux提权方法相对来讲有七八种方式…

NX二次开发UF_CURVE_create_arc_3point 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_create_arc_3point Defined in: uf_curve.h int UF_CURVE_create_arc_3point(tag_t point1, tag_t point2, tag_t point3, UF_CURVE_limit_p_t limit_p [ 2 ] , tag_t supp…

不同路径(力扣LeetCode)动态规划

不同路径 题目描述 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&…

基于Tomcat+Eclipse+Mysql开发的图书信息管理系统

基于TomcatEclipseMysql开发的图书信息管理系统 项目介绍&#x1f481;&#x1f3fb; 环境要求&#xff1a; eclipse j2ee mysql5 jdk8 tomcat9 必须按上述环境要求运行项目&#xff0c;否则将无法运行&#xff01; 步骤&#xff1a; 1.打开eclipse导入项目 2.修改book-context…

Nginx系列-正向代理和反向代理

Nginx系列-正向代理和反向代理 文章目录 Nginx系列-正向代理和反向代理1. 三个对象2. 两种场景代理2.1. 正向代理2.2. 反向代理 3. 两种场景的对比3.1 为什么叫做反向代理3.2 正向代理和反向代理的作用 1. 三个对象 客户端&#xff1a;发出请求到代理&#xff0c;并接收代理的…

第29期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

扩散模型DDPM学习笔记

扩散模型DDPM 文章目录 扩散模型DDPM如何运作基本概念训练过程推理过程&#xff1a; 目标损失函数推导评估标准 论文地址&#xff1a; Denoising Diffusion Probabilistic Models (DDPM) 如何运作 ​ 从guassian distribution进行采样得到一个噪声的图片&#xff0c;图片大小…

Spring Boot + MyBatis-Plus实现数据库读写分离

文章目录 1. 引言2. MyBatis-Plus简介3. 准备工作4. 配置数据源5. 配置MyBatis-Plus6. 创建实体类和Mapper接口7. 编写Service8. 控制器层9. 测试10. 数据库读写分离的原理11. 拓展11.1. 动态数据源11.2. 多数据源事务管理11.3. 多租户支持 12. 总结 &#x1f389;Spring Boot …

西南科技大学数字电子技术实验二(SSI逻辑器件设计组合逻辑电路及FPGA实现 )预习报告

一、计算/设计过程 说明:本实验是验证性实验,计算预测验证结果。是设计性实验一定要从系统指标计算出元件参数过程,越详细越好。用公式输入法完成相关公式内容,不得贴手写图片。(注意:从抽象公式直接得出结果,不得分,页数可根据内容调整) 1、1位半加器 真值表: 逻…

华为云(HECS)docker环境下安装jenkins

Jenkins是一个开源的自动化工具&#xff0c;可以自动化地完成构建、测试、交付或部署等任务。总之重点就是三个字&#xff1a;自动化&#xff0c;至于如何实现这些功能&#xff0c;Jenkins基于插件化的机制&#xff0c;提供了众多的插件来完成持续集成CI与持续部署CD。 【持续…

使用 Mybatis 的 TypeHandler 存取 Postgresql jsonb 类型

文章目录 使用 TypeHandler 存取 Postgresql jsonb 类型常见错误column "" is of type jsonb but expression is of type character varying 使用 TypeHandler 存取 Postgresql jsonb 类型 首先在数据库表中定义 jsonb 类型&#xff1a; create table tb_user_info…

Qt右键菜单+动作+qss案例

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//设置界面颜色样式this->setStyleSheet("background-color:rgb(54,54,54)");//创建文件菜单QMenu *fileMenuItems new QMenu;//菜单添加iconfileMenuItems->se…

【安装指南】MySQL和Navicat下载、安装及使用详细教程

目录 ⛳️1.【MySQL】安装教程 1.1 获取下载包 1.2 MySQL安装 1.2.1 MySQL工具安装 1.2.2 MySQL环境变量 1.2.3 验证MySQL安装成功 ⛳️2.【Navicat-v15】的安装和无限使用 ⛳️3.【测试Navicat连接MySQL】 ⛳️1.【MySQL】安装教程 1.1 获取下载包 前往官网获取压缩包…

Python---lambda表达式

普通函数与匿名函数 在Python中&#xff0c;函数是一个被命名的、独立的完成特定功能的一段代码&#xff0c;并可能给调用它的程序一个返回值。 所以在Python中&#xff0c;函数大多数是有名函数 > 普通函数。但是有些情况下&#xff0c;我们为了简化程序代码&#xff0c;…

Mysql的二阶段提交

先看执行器与InnoDB引擎是如何更新一条指定的数据的 可以看到&#xff0c;InnoDB在写redo log时&#xff0c;并不是一次性写完的&#xff0c;而有两个阶段&#xff0c;Prepare与Commit阶段&#xff0c;这就是"两阶段提交"的含义。 为什么要写redo log&#xff0c;不…

羊大师介绍,备孕阶段饮食规划及对羊奶的影响

备孕期是夫妻俩为了生育健康宝宝所准备的重要阶段&#xff0c;在这个阶段&#xff0c;营养的摄入对于双方的身体健康和胚胎的发育至关重要。而羊奶作为一种营养丰富的饮品&#xff0c;备孕期间是否能喝羊奶一直是备孕夫妇们关注的话题。本文小编羊大师将会详细解答这一问题&…

uniapp微信小程序中阻止事件冒泡

开发场景&#xff1a;列表中展示地块的数据信息&#xff0c;用户可以点击列表进入地块的详情界面&#xff0c;也可以点击列表中的星星按钮进行收藏 遇到的问题&#xff1a;每次点击星星的时候&#xff0c;都会触发父级的点击事件&#xff0c;从而进入到详情界面 原本的代码&am…
最新文章