C# Web控件与数据感应之 填充 HtmlTable

目录

关于 HtmlTable

HtmlTable与BaseDataList的区别

准备数据源

​范例运行环境

FillTable 方法

设计与实现

模板样例输出

Automatic 模式填充

​         DynamicRows 模式填充

StaticRows 模式填充

小结


关于 HtmlTable

数据感应也即数据捆绑,是一种动态的,Web控件与数据源之间的交互,HtmlTable 控件表示为一个服务器控件,隶属于 System.Web.UI.HtmlControls 集合,对于客户端输出即 table 标签元素,table 表格的主要作用就是数据输出 ,本文将介绍 C# 实现操作 HtmlTable 服务器控件实现数据集表数据的轻量化输出与显示。

HtmlTable与BaseDataList的区别

HtmlTable 与诸如 DataGrid、GridView 都可用于数据输出 ,主要区别在于:

(1)前者以属于System.Web.UI.HtmlControls 集合,后者 Microsoft.Web.UI.WebControls 集合

(2)HtmlTable 可实现 table 元素的一些操作,如行、列、单元格及样式设置,而 BaseDataList 除可实现 HtmlTable 的基本控制外,还可以绑定数据源、绑定事件、绑定列控件等更加强大的功能。

(3)对于数据集合访问 HtmlTable 通过 Rows ,列集合为 Cells;而 BaseDataList  通过 Items ,列集合为 Colums。

准备数据源

我们在 MS SQL Server 创建 pub_ChinaPay(支付状态代码表),其结构如下表:

序号字段名类型说明
1valuechar(4)支付状态代码,唯一键
2textnvarchar(14)状态名称
3sortidsmallint排序号

执行如下 创建表的 SQL 语句:

CREATE TABLE [dbo].[pub_ChinaPay](
	[value] [char](4) NOT NULL,
	[text] [nvarchar](14) NOT NULL,
	[sortid] [smallint] NULL,
 CONSTRAINT [PK_pub_ChinaPay] PRIMARY KEY CLUSTERED 
(
	[value] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

执行如下SQL语句,创建一些数据:

insert into pub_ChinaPay(value,text,sortid) values('****','默认状态',1)
insert into pub_ChinaPay(value,text,sortid) values('    ','待支付',2)
insert into pub_ChinaPay(value,text,sortid) values('1001','消费交易成功',3)
insert into pub_ChinaPay(value,text,sortid) values('1003','退款提交成功',4)
insert into pub_ChinaPay(value,text,sortid) values('1005','退款撤销成功',5)
insert into pub_ChinaPay(value,text,sortid) values('0003','交易失败',6)
insert into pub_ChinaPay(value,text,sortid) values('6666','微信退款申请成功',7)

通过查询分析器,执行查询SQL语句,显示如下图:

最后我们将数据填充到 DataReader ,并生成对应的二维数组。

范例运行环境

操作系统: Windows Server 2019 DataCenter

数据库:Microsoft SQL Server 2016

.net版本: .netFramework4.0 或以上

开发工具:VS2019  C#

FillTable 方法

设计与实现

FillTable 方法主要是通过 object[,] 二维对象数组数据源进行提取并呈现在 HtmlTable 表格控件上,其参数设置见下表:

序号参数名类型说明
1tbSystem.Web.UI.HtmlControls.HtmlTable要输出的 HtmlTable 对象
2ftFillType

填充模式枚举:

public enum FillType
 { Automatic,DynamicRows,

StaticRows
}

后续将讲解这些模式的区别

3SpaceInEmptyCellbool对于空字符串输出,是否替换为&nbsp 输出以达到更好的显示效果
4MinClearRowsCountint当输出数据行为空时,清除模板表格行的阀值,设为0,则表示全部清空,不显示输出表格的任何元素
5refStartRowIdint指定数据输出的起始行
6refCopyRowIdint指定要复制哪一行的格式进行输出
7allowToHTMLbool是否允许将数据解析为HTML样式输出,默认为 false

GetReaderData 方法可以访问数据库数据表进行查询结果的提取,并转化为 object[,] 二维数组,其参数设置见下表:

序号参数名类型说明
1DbServerTypestring目前支持 "oracle"、 "dm8",其它字符串均视为 MS SQL Server
strConnstring对应数据库的连接字符串
2_sqlstring要执行的SQL语句命令行
3parasArrayList

要赋值的参数对象,逐个添加到ArrayList里,请注意参数为实体数据参数对象,如 MS SQL Server ,请传递如下代码:

ArrayList.Add(new SqlParameter("参数名",参数值)); 

4hastitlebool输出是否包含字段列标题
5ctCommandType

System.Data.CommandType 枚举,可包括:

StoredProcedure(存储过程)
TableDirect(直接表查询)
Text(文本查询)该值为默认值

GetReaderData 方法实现代码如下:

int RowsCount = 0;
int ErrorNum = 0;
string ErrorMessage = "";

public object[,] GetReaderData(string DbServerType,string strConn,string _sql,ArrayList paras,bool hastitle,CommandType ct)
{


			if((DbServerType.ToLower()=="")||(DbServerType.ToLower()=="sqlserver"))
			{

				SqlConnection Conn = new SqlConnection(strConn );
				SqlCommand Cmd = new SqlCommand();
				Cmd.CommandType=ct;
				Cmd.Connection = Conn;

				SqlDataReader myDr;
				Cmd.CommandText =_sql;
				if(paras!=null)
				{
					for(int i=0;i<paras.Count;i++)
					{
						Cmd.Parameters.Add((SqlParameter)paras[i]);
					}
				}


				try
				{
					Conn.Open();

					myDr = Cmd.ExecuteReader();
					
					ArrayList rowdata = new ArrayList();
					int _fieldcount=myDr.FieldCount;
					Object[] colvalues = new Object[_fieldcount];
					for(int i=0;i<_fieldcount;i++)
					{
						colvalues[i]=myDr.GetName(i);
					}
					if(hastitle)
					rowdata.Add(colvalues);
					while(myDr.Read())
					{
						Object[] values = new Object[_fieldcount];
						myDr.GetValues(values);
						rowdata.Add(values);
						RowsCount++;
					}
					myDr.Close();
					object[,] rv=new object[rowdata.Count,_fieldcount];
					for(int i=0;i<rowdata.Count;i++)
					{
						for(int j=0;j<_fieldcount;j++)
						{
							rv[i,j]=((object[])rowdata[i])[j];
						}
					}
					return rv;

				}

				catch (SqlException e)
				{
					ErrorMessage=e.Message;
					return null;
				}

				finally
				{
					Conn.Close();
					Conn.Dispose();
				}
			}//sqlserver
			if(DbServerType.ToLower()=="oracle")
			{

				OracleConnection Conn = new OracleConnection(strConn );
				OracleCommand Cmd = new OracleCommand();

				Cmd.Connection = Conn;

				OracleDataReader myDr;
				Cmd.CommandText =_sql;
				if(paras!=null)
				{
					for(int i=0;i<paras.Count;i++)
					{
						Cmd.Parameters.Add((OracleParameter)paras[i]);
					}
				}


				try
				{
					Conn.Open();

					myDr = Cmd.ExecuteReader();
					ArrayList rowdata = new ArrayList();
					int _fieldcount=myDr.FieldCount;
					Object[] colvalues = new Object[_fieldcount];
					for(int i=0;i<_fieldcount;i++)
					{
						colvalues[i]=myDr.GetName(i);
					}
					if(hastitle)
						rowdata.Add(colvalues);
					while(myDr.Read())
					{
						Object[] values = new Object[_fieldcount];
						myDr.GetValues(values);
						rowdata.Add(values);
						RowsCount++;
					}
					myDr.Close();
					object[,] rv=new object[rowdata.Count,_fieldcount];
					for(int i=0;i<rowdata.Count;i++)
					{
						for(int j=0;j<_fieldcount;j++)
						{
							rv[i,j]=((object[])rowdata[i])[j];
						}
					}
					return rv;

				}

				catch (OracleException e)
				{
					ErrorMessage=e.Message;
					return null;
				}

				finally
				{
					Conn.Close();
					Conn.Dispose();
				}
			}//oracle
            if (DbServerType.ToLower() == "dm8")
            {

                DmConnection Conn = new DmConnection(strConn);
                DmCommand Cmd = new DmCommand();
                Cmd.CommandType = ct;
                Cmd.Connection = Conn;

                DmDataReader myDr;
                Cmd.CommandText = _sql;
                if (paras != null)
                {
                    for (int i = 0; i < paras.Count; i++)
                    {
                        Cmd.Parameters.Add((DmParameter)paras[i]);
                    }
                }


                try
                {
                    Conn.Open();

                    myDr = Cmd.ExecuteReader() as DmDataReader;

                    ArrayList rowdata = new ArrayList();
                    int _fieldcount = myDr.FieldCount;
                    Object[] colvalues = new Object[_fieldcount];
                    for (int i = 0; i < _fieldcount; i++)
                    {
                        colvalues[i] = myDr.GetName(i);
                    }
                    if (hastitle)
                        rowdata.Add(colvalues);
                    while (myDr.Read())
                    {
                        Object[] values = new Object[_fieldcount];
                        myDr.GetValues(values);
                        rowdata.Add(values);
                        RowsCount++;
                    }
                    myDr.Close();
                    object[,] rv = new object[rowdata.Count, _fieldcount];
                    for (int i = 0; i < rowdata.Count; i++)
                    {
                        for (int j = 0; j < _fieldcount; j++)
                        {
                            rv[i, j] = ((object[])rowdata[i])[j];
                        }
                    }
                    return rv;

                }

                catch (DmException e)
                {
                    ErrorMessage = e.Message;
                    return null;
                }

                finally
                {
                    Conn.Close();
                    Conn.Dispose();
                }
            }//dm8
            return null;
}//getreaddata

FillTable 方法实现代码如下:

ArrayList paras=new ArrayList();
string refSql="";
bool hastitle=false;
System.Data.CommandType ct=System.Data.CommandType.Text;
public void FillTable(HtmlTable tb, FillType ft, bool SpaceInEmptyCell, int MinClearRowsCount, int refStartRowId,int refCopyRowId,bool allowToHTML)
 {
      object[,] ReaderData = GetReaderData("SqlServer","您的连接串","",paras,hastitle,ct);

                if (ReaderData == null && RowsCount==0)
                {
                    while (tb.Rows.Count > MinClearRowsCount)
                    {
                        tb.Rows.RemoveAt(tb.Rows.Count - 1);
                    }

                    return;
                }
                if (ft == FillType.Automatic || ft==FillType.DynamicRows || ft==FillType.StaticRows)
                {
                    if (ft == FillType.Automatic)
                    {
                        int addcells = ReaderData.GetLength(1) - tb.Rows[0].Cells.Count;
                        for (int i = 0; i < tb.Rows.Count; i++)
                        {
                            for (int j = 0; j < addcells; j++)
                            {
                                HtmlTableCell tc = new HtmlTableCell();
                                if (allowToHTML == true)
                                {
                                    tc.Attributes.Add("ByHTML", "true");
                                }
                                tb.Rows[i].Cells.Add(tc);
                            }
                        }
                        if (tb.Rows.Count == 2)
                        {
                            for (int j = 0; j < ReaderData.GetLength(1); j++)
                            {
                                string _fieldname = ReaderData[0, j].ToString();
                                tb.Rows[0].Cells[j].InnerText = _fieldname;
                            }
                        }
                    }
                    int startRowID = tb.Rows.Count - 1;
                    int copyRowID = 0;
                    if (ft == FillType.StaticRows)
                    {
                        if (HasTitle == true)
                        {
                            startRowID = tb.Rows.Count > 1 ? 1 : 0;
                        }
                        else
                        {
                            startRowID = 0;
                        }
                    }
                    if (refStartRowId != -1) startRowID = refStartRowId;
                    if (refCopyRowId != -1) copyRowID = refCopyRowId;
                    for (int i = (HasTitle == true ? 1 : 0); i < ReaderData.GetLength(0); i++)
                    {
                        if (startRowID>tb.Rows.Count-1) break;
                        for (int j = 0; j < ReaderData.GetLength(1); j++)
                        {
                            if (j > tb.Rows[copyRowID].Cells.Count - 1) break;
                            HtmlTableCell td = tb.Rows[startRowID].Cells[j];
                            if (td.Attributes["ByHTML"] == null)
                            {
                                td.InnerText = ReaderData[i, j].ToString();
                            }
                            else
                            {
                                td.InnerHtml = allowToHTML == true ? (ReaderData[i, j].ToString()) : ReaderData[i, j].ToString();;
                            }
                            

                            if (td.InnerText == "" && SpaceInEmptyCell == true) td.InnerHtml="&nbsp;";
                        }
                        if (i == ReaderData.GetLength(0)-1) break;
                        if (ft == FillType.Automatic || ft == FillType.DynamicRows)
                        {
                            HtmlTableRow tr = new HtmlTableRow();
                            tb.Rows.Add(tr);
                            for (int k = 0; k < tb.Rows[copyRowID].Cells.Count; k++)
                            {
                                HtmlTableCell prv_tc = tb.Rows[startRowID].Cells[k];
                                HtmlTableCell tc = new HtmlTableCell();
                                tr.Cells.Add(tc);
                                CloneStyles(prv_tc, tc);
                            }
                        }
                        startRowID ++;
                    }
                }
}//fill table
void CloneStyles(HtmlControl obj, HtmlControl newobj)
{
                IEnumerator keys = obj.Style.Keys.GetEnumerator();
                while (keys.MoveNext())
                {
                    String key = (String)keys.Current; newobj.Style[key] = obj.Style[key];
                }
                IEnumerator keys2 = obj.Attributes.Keys.GetEnumerator();
                while (keys2.MoveNext())
                {
                    String key = (String)keys2.Current; newobj.Attributes[key] = obj.Attributes[key];
                }

}

模板样例输出

在方法设计的章节里介绍了 FillType (即填充类型的枚举)

Automatic 模式填充

全自动填充,表示行、列均不固定,全由SQL查询结果动态输出,仅设置首行首列的样式即可,如下图:

 前端代码示例 :

<table id="tjTable" runat="server" align="center" border="1" style="width: 700px; border:1px solid #000000;border-collapse:collapse">
        <tr><td>标题</td></tr>
        <tr>
            <td>
                &nbsp;</td>
         </tr>
</table>

调用示例如下代码:

string refSQL = "select value,text,sortid from pub_chinaPay order by sortid";
FillTable(tjTable, FillType.Automatic, true, 0, 1, 1);

输出结果如下图 

可以看到行列完全由SQL语句决定进行原始输出,行与列均为动态输出 。 

DynamicRows 模式填充

动态行填充,表示行输出不固定,已预知列的输出,仅需要设置首行标题列和数据行的样式即可,如下图:

 前端代码示例 :

<table id="tjTable" runat="server" align="center" border="1" style="width: 700px; border:1px solid #000000;border-collapse:collapse">
        <tr>
            <td>
               状态代码</td>
            <td>
               状态名称</td>
            <td>
               排序号</td>
        </tr>
        <tr>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
        </tr>
    </table>

调用示例如下代码:

string refSQL = "select value,text,sortid from pub_chinaPay order by sortid";
FillTable(tjTable, FillType.DynamicRows, true, 0, 1, 1);

输出结果如下图 

可以看到行为动态输出,标题列为预期的设置 。 

StaticRows 模式填充

静态填充,表示行、列均固定,由SQL查询结果根据预设输出,可设置每行每列的样式,如下图:

 前端代码示例 :

<table id="tjTable" runat="server" align="center" border="1" style="width: 700px; border:1px solid #000000;border-collapse:collapse">
        <tr>
            <td>
               状态代码</td>
            <td>
               状态名称</td>
            <td>
               排序号</td>
        </tr>
        <tr>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
        </tr>
        <tr>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
        </tr>
        <tr>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
        </tr>
        <tr>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
        </tr>
        <tr>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
        </tr>
        <tr>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
        </tr>
        <tr>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
        </tr>
        <tr>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
            <td>
                &nbsp;</td>
        </tr>
    </table>

调用示例如下代码:

string refSQL = "select value,text,sortid from pub_chinaPay order by sortid";
FillTable(tjTable,FillType.StaticRows, true, 0, 1, 1);

输出结果如下图 

可以看到行有冗余,因此静态行模式仅输出列和行的可见区域,即溢出和不足均不显示 。 

小结

关于 HtmlTable 的其它详细操作和介绍,可参照如下链接:

https://learn.microsoft.com/zh-cn/dotnet/api/system.web.ui.htmlcontrols.htmltable?view=netframework-4.8.1&redirectedfrom=MSDN

关于填充模式,是在实际的应用场景里进行输出 ,比如全动态适合于依赖SQL语句控制度较高的场景,而动态行则是比较常见的一种输出方式,静态行输出则比如我们提供一种填写表格,已经预设好最大行数,为体现整体统一的输出风格而应用。所以,我们可以根据自己的实际需要改造输出 的模式,本示例代码仅供您参考。 

感谢您的阅读,希望本文能够对您有所帮助。

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

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

相关文章

前端canvas绘图,利用canvas在图片上面绘制标记以及给canvas添加点击事件。

前端canvas绘图&#xff0c;利用canvas在图片上面绘制标记以及给canvas添加点击事件。 需要实现的效果如下图: 首先需要一个承载的核心画布 <canvas id"canvas" width"800" height"600"></canvas>全部代码&#xff1a; <!DOCT…

Web3的应用场景分析

Web3&#xff0c;即基于区块链技术的去中心化互联网&#xff0c;正逐渐改变我们与数字世界的互动方式。以下是Web3的一些主要应用场景。Web3技术正在各个领域推动创新&#xff0c;创造更多透明、开放和去中心化的解决方案&#xff0c;为用户带来更高的自主权和安全性。北京木奇…

Python语法详解module3(组合数据类型列表、元组、字典、集合详细用法)

目录 一、列表列表的创建多维列表列表的访问和修改列表的添加和删除列表的遍历使用 for 循环遍历使用 while 循环遍历同时遍历索引和元素列表推导式 常用的列表函数len()sort()reverse()index()count()extend()clear() 二、元组创建元组访问元组元素元组的不可变性元组的优点元…

【Linux】(三)—— 文件管理和软件安装

文件管理 Linux的文件管理是系统管理中的核心部分&#xff0c;它涉及到如何组织、访问、修改和保护文件及目录结构。 目录 文件管理基本概念常用命令查看和切换目录创建文件和目录删除文件和目录文件拷贝移动和重命名文件文件查看cat文件查看more查找文件查找文本 数据流和管道…

软件测试报告实际案例模板(项目测试文档doc原件)

软件测试报告在软件开发过程中起着至关重要的作用&#xff0c;主要有以下几个主要原因&#xff1a; 1、确保软件质量 2、提供决策支持 3、记录测试过程和结果 4、促进沟通和协作 5、符合标准和法规要求 6、改进测试流程和策略 7、降低风险 软件开发全套资料获取进主页或者本文末…

SEACells:元细胞分析

元细胞是从单细胞测序数据中衍生的细胞分组&#xff0c;代表高度精细的不同细胞状态。在这里&#xff0c;作者介绍了单细胞细胞状态聚集 (SEACells)&#xff0c;这是一种用于识别元细胞的算法&#xff0c;它克服了单细胞数据的稀疏性&#xff0c;同时保留了传统细胞聚类所掩盖的…

LW-DETR:实时目标检测的Transformer, Apache-2.0 开源可商用,实验超 YOLOv8

LW-DETR&#xff1a;实时目标检测的Transformer&#xff0c; Apache-2.0 开源可商用&#xff0c;实验超 YOLOv8 LW-DETR 架构实例化高效训练高效推理 目的与解法拆解ViT编码器和DETR解码器多级特征图聚合变形交叉注意力窗口注意力和全局注意力 论文&#xff1a;https://arxiv.o…

QT系列教程(9) 主窗口学习

简介 任何界面应用都有一个主窗口&#xff0c;今天我们谈谈主窗口相关知识。一个主窗口包括菜单栏&#xff0c;工具栏&#xff0c;状态栏&#xff0c;以及中心区域等部分。我们先从菜单栏说起 菜单栏 我们创建一个主窗口应用程序, 在ui文件里的菜单栏里有“在这里输入”的一个…

AI大底座核心平台:百度百舸AI异构计算平台(AI IaaS)与AI中台(AI PaaS)

AI大底座正是整合了以上端到端全要素技术能力&#xff0c;将基础架构IaaS与应用平台PaaS能力深度融合&#xff0c;面向企业和产业AI生 产与应用的全生命周期提供完整解决方案。 百舸AI异构计算平台是AI IaaS层的核心平台&#xff0c;包括AI计算、AI存储、AI加速、AI容器四层套件…

算法人生(19): 从“LangChain的六大组件”看“个人职业规划”

我们今天要说说和大模型有着密切关系的Langchain &#xff0c;它提供了一个平台&#xff0c;让开发者可以更加轻松地训练、部署和管理这些大模型。具体来说&#xff0c;Langchain 可以通过提供高性能的计算资源、灵活的模型管理和部署选项、以及丰富的监控和调试功能&#xff0…

「动态规划」如何求下降路径最小和?

931. 下降路径最小和https://leetcode.cn/problems/minimum-falling-path-sum/description/ 给你一个n x n的方形整数数组matrix&#xff0c;请你找出并返回通过matrix的下降路径的最小和。下降路径可以从第一行中的任何元素开始&#xff0c;并从每一行中选择一个元素。在下一…

CentOS 环境下 PostgreSQL 在线安装和源码安装详解

1、内容概述 昨天给大家简单的介绍了一下 PostgreSQL,并且在Windows系统上通过图形化界面的方式搭建好了环境&#xff0c;今天我们就来学习一下如何在Linux 系统上搭建 PostgreSQL环境&#xff0c;我会给大家介绍在线安装、离线源码安装以及Docker 安装三种方式。 2、在线安装…

umijs 服务端渲染(SSR) 指南

umijs 服务端渲染&#xff08;SSR&#xff09; 指南 Umi 是什么&#xff1f; Umi&#xff0c;中文可发音为乌米&#xff0c;是可扩展的企业级前端应用框架。Umi 以路由为基础的&#xff0c;同时支持配置式路由和约定式路由&#xff0c;保证路由的功能完备&#xff0c;并以此进…

枚举(enum)+联合体(union)

枚举联合 一.枚举类型1.枚举类型的声明2.枚举类型的优点3.枚举类型的使用 二.联合体1.联合体类型的声明2.联合体的特点3.相同成员的结构体和联合体对比4.联合体大小的计算5.联合体的练习&#xff08;判断大小端&#xff09;6.联合体节省空间例题 一.枚举类型 1.枚举类型的声明…

安全U盘和普通U盘有什么区别?

安全U盘&#xff08;也称为加密U盘或安全闪存驱动器&#xff09;与普通U盘肯定是有一些区别的&#xff0c;从字面意思上来看&#xff0c;就能看出&#xff0c;安全U盘是能够保护文件数据安全性的&#xff0c;普通U盘没这一些功能的&#xff0c;可随意拷贝文件&#xff0c;不防盗…

Hadoop3:MapReduce源码解读之Mapper阶段的TextInputFormat切片机制(3)

Job那块的断点代码截图省略&#xff0c;直接进入切片逻辑 参考&#xff1a;Hadoop3&#xff1a;MapReduce源码解读之Mapper阶段的Job任务提交流程&#xff08;1&#xff09; 5、TextInputFormat源码解析 类的继承关系 它的内容比较少 重写了两个父类的方法 这里关心一下泛型…

《开源模型食用指南》基于Linux环境快速部署开源模型,更适合中国宝宝的部署教程

今天给大家推荐一个非常适合中国宝宝学习的专属大模型教程&#xff0c;也就是它《开源模型食用指南》&#xff01; 当前百模大战正值火热&#xff0c;开源LLM层出不穷。 如今国内外已经涌现了众多优秀开源LLM&#xff0c;国外如LLaMA、Alpaca&#xff0c;国内如ChatGLM、BaiCh…

【Unity Shader入门精要 第13章】使用深度和法线纹理(一)

1. 原理 深度纹理的本质是一张RenderTexture&#xff0c;只不过其中记录的不是颜色值&#xff0c;而是一个深度值 这些深度值来自于顶点在空间变换后得到的归一化设备坐标&#xff08;NDC&#xff09;的Z值 由于NDC坐标的分量取值范围在[-1, 1]之间&#xff0c;要使颜色值能…

欧盟EDPS发布首份生成式人工智能与数据安全指南解读

6月3日&#xff0c;欧洲数据保护监督机构&#xff08;EDPS&#xff09;在其官网上发布了题为《生成式人工智能与EUDPR》的指南&#xff08;注&#xff1a;EUDPR指的是《欧盟2018/1725号条例》&#xff09;&#xff0c;这是首份适用于欧盟机构的人工智能与数据安全指南。 01 指南…

STM32 SPI驱动读取LSM6DSRTR

提示&#xff1a;通过SPI驱动读取传感器数据 文章目录 前言一、LSM6DSRTR二、配置步骤1.配置SPI2.引入 LSM驱动库3.结果 总结 前言 制作一个倾角传感器&#xff0c;通过SPI读取LSM6DSRTR的加速度数据转换为角度&#xff0c;不用IIC的原因是考虑IIC通讯的协议过于繁琐&#xff…