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

news2024/11/24 22:35:37

文章目录

  • 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.coloradmin.cn/o/1265456.html

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

相关文章

dart多线程双向通信的案例----【小学4年级课程】

下面是运行后的打印顺序 I/flutter (20170): 上班 I/flutter (20170): 这里是校长室:main I/flutter (20170): 这里是饭堂:fantang1 I/flutter (20170): 这里是收发室--检查小孩发回去给他妈妈的信息是&#xff1a;我是秘书的儿子&#xff0c;我来到在校长室了。校长今晚想吃羊…

项目:基于UDP的网络聊天室

项目需求&#xff1a; 1.如果有用户登录&#xff0c;其他用户可以收到这个人的登录信息 2.如果有人发送信息&#xff0c;其他用户可以收到这个人的群聊信息 3.如果有人下线&#xff0c;其他用户可以收到这个人的下线信息 4.服务器可以发送系统信息 服务器代码&#xff1a; #i…

深入了解Java8新特性-日期时间API:LocalDateTime类

阅读建议 嗨&#xff0c;伙计&#xff01;刷到这篇文章咱们就是有缘人&#xff0c;在阅读这篇文章前我有一些建议&#xff1a; 本篇文章大概22000多字&#xff0c;预计阅读时间长需要20分钟以上。本篇文章的实战性、理论性较强&#xff0c;是一篇质量分数较高的技术干货文章&…

离散数学-集合论基础

3.1集合的基本概念 1&#xff09;集合及元素 2&#xff09;集合的表示 3&#xff09;集合的关系 4&#xff09;特殊集合 3.2集合的运算 并、交、差、对称差 3.3集合的划分与覆盖 3.4排斥包含管理 3.1集合的基本概念 1&#xff09;集合及元素 将某种具有同种属性的个体…

记录Windows下安装redis的过程

开源博客项目Blog支持使用EasyCaching组件操作redis等缓存数据库&#xff0c;在继续学习开源博客项目Blog之前&#xff0c;准备先学习redis和EasyCaching组件的基本用法&#xff0c;本文记录在Windows下安装redis的过程。   虽然redis官网文档写着支持Linux、macOS、Windows等…

pyecharts绘制自定义点+连线取消箭头+时间帧叠加

pyecharts之Geo地图大法&#xff08;详解&#xff0c;代码带注释效果图&#xff09; 近期项目上有地图自定义绘点连线分严重等级的需求&#xff0c;整了&#xff0c;分开处理啥都好说&#xff0c;多个数据放在同一维度的时候&#xff0c;只恨pyecharts的开发者为什么把功能整得…

简介vue

目录 一、介绍 渐进式框架​ 单文件组件​ 选项式 API (Options API)​ 组合式 API (Composition API)​ 该选哪一个&#xff1f;​ 创建一个 Vue 应用 应用实例​ 根组件​ DOM 中的根组件模板 应用配置​ 多个应用实例​ 一、介绍 Vue (发音为 /vjuː/&#xff…

Selenium 学习(0.17)——软件测试之测试用例设计方法——白盒测试——逻辑覆盖法(条件覆盖和条件判定覆盖)

条件覆盖 设计测试用例&#xff0c;使每个判断中每个条件的可能取值至少满足一次。 条件判定覆盖 通过设计足够的测试用例&#xff0c;满足如下条件&#xff1a; 所有条件的可能至少执行一次的取值 所有判断的可能结果至少执行一次 条件判定覆盖同时满足判定覆…

灰度发布专题---3、Nginx+Lua灰度发布

上一章已经讲解了配置文件灰度发布、应用版本灰度发布、API网关灰度发布实现&#xff0c;但如果用户这时候在代理层如何做灰度发布呢&#xff1f; 代理层灰度发布分析 用户无论访问应用服务还是静态页&#xff0c;都要经过Nginx代理层&#xff0c;我们可以在Nginx这里做灰度发…

读像火箭科学家一样思考笔记12_实践与测试(下)

1. 舆论的火箭科学 1.1. 如果苹果违反了“即飞即测”原则&#xff0c;那苹果的iPhone就不会问世了 1.1.1. iPhone在其上市前的民意调查中相当失败 1.1.1.1. iPhone不可能获得太大市场份额&#xff0c;不可能。 1.1.1.1.1. 微软前CEO史蒂夫鲍尔默&#xff08;Steve Ballmer&…

AIGC系列之:GroundingDNIO原理解读及在Stable Diffusion中使用

目录 1.前言 2.方法概括 3.算法介绍 3.1图像-文本特征提取与增强 3.2基于文本引导的目标检测 3.3跨模态解码器 3.4文本prompt特征提取 4.应用场景 4.1结合生成模型完成目标区域生成 4.2结合stable diffusion完成图像编辑 4.3结合分割模型完成任意图像分割 1.前言 …

第20章 多线程

创建线程 继承Thread 类 Thread 类时 java.lang 包中的一个类&#xff0c;从类中实例化的对象代表线程&#xff0c;程序员启动一个新线程需要建立 Thread 实例。 Thread 对象需要一个任务来执行&#xff0c;任务是指线程在启动时执行的工作&#xff0c;start() 方法启动线程…

第一百八十二回 自定义一个可以滑动的刻度尺

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法3. 示例代码4. 内容总结我们在上一章回中介绍了"如何绘制阴影效果"相关的内容,本章回中将介绍 如何自定义一个可以滑动的刻度尺.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 任何优美的文字在图…

[SaaS] 广告创意中stable-diffusion的应用

深度对谈&#xff1a;广告创意领域中 AIGC 的应用这个领域非常快速发展&#xff0c;所以你应该保持好奇心&#xff0c;不断尝试新事物&#xff0c;不断挑战自己。https://mp.weixin.qq.com/s/ux9iEABNois3y4wwyaDzAQ我对AIGC领域应用调研&#xff0c;除了MaaS服务之外&#xff…

电荷泵升压/降压电路

一、升压\降压电路原理分析 1、升压电路 电荷泵升压电路 VoutVa5V 5V_PLUS0V时&#xff0c;Va给C2充电&#xff0c;C2上节点电压比C2下节点电压高Va&#xff1b; 5V_PLUS5V时&#xff0c;C2电压不能突变&#xff0c;C2上节点电压依然比C2下节点电压高Va&#xff0c;但C2下节点…

supermap-iserver激活教程(linux)

本篇只介绍linux临时许可激活教程&#xff0c;windows的原理一摸一样不做赘述。 1.下载许可中心&#xff08;web版&#xff09; SuperMap技术资源中心|为您提供全面的在线技术服务 2.解压 supermap-bslicense-server-3.0.24-linux-x64.tar.gz tar -zxvf supermap-bslicense…

选择排序以及改进方案

选择排序以及改进方案 介绍&#xff1a; 选择排序是一种简单直观的排序算法&#xff0c;它的基本思想是在未排序序列中选择最小&#xff08;或最大&#xff09;的元素&#xff0c;然后将其放在已排序序列的末尾。选择排序的过程就像是每次从待排序的元素中选择最小的一个&…

Java基于ssm的租房求租网站房东直租中介托管房屋出租项目源码

演示视频 https://www.bilibili.com/video/BV1Lh411J7ic/?share_sourcecopy_web&vd_source11344bb73ef9b33550b8202d07ae139b 可转成springboot项目。 主要功能&#xff1a;租户可以浏览搜索收藏房源&#xff0c;预约看房&#xff0c;发布求租信息。房东可以发布管理房源…

2023-11-28-直播单细胞图表美化-seurat数据结构 featureplot dotplot vlnplot

单细胞常见的可视化方式有DimPlot&#xff0c;FeaturePlot &#xff0c;DotPlot &#xff0c;VlnPlot 和 DoHeatmap几种 &#xff0c;Seurat中均可以很简单的实现&#xff0c;但是文献中的图大多会精美很多。 之前 跟SCI学umap图| ggplot2 绘制umap图&#xff0c;坐标位置 &am…

SSL证书实惠品牌——JoySSL

随着互联网的普及和发展&#xff0c;网络安全问题日益严重。为了保护网站数据的安全&#xff0c;越来越多的网站开始使用SSL证书。JoySSL证书作为一款高性价比的SSL证书&#xff0c;受到了广泛的关注和好评。 目前市面上主流的证书基本上都是国外证书&#xff0c;也就是说你在验…