
简介面向asp.net初学者及企业资产管理员的一套固定资产管理系统源码与SQL Server数据库配套包完整覆盖固定资产从登记到报废的全生命周期管理包括固定资产查询/管理、新增、批量异动、维修、报废、审核流程以及事业部、部门、资产一级/二级类别等基础数据维护。资源共231个文件以C#业务逻辑代码73个cs、aspx页面71个aspx为主体辅以SQL Server数据库文件mdf/ldf、前端样式与脚本css/js、Excel导出模板及打印相关页面压缩包仅940KB。系统内置管理员和会员双角色管理员admin可设置每个用户的操作权限并审核新用户注册普通用户则可发起新增资产、异动、维修、报废等申请配合“我管理的固定资产”模块实现责任到人。页面采用固定前列加横向滚动的方式展示宽表支持查询打印固定资产标识卡及导出Excel业务逻辑完整、目录结构清晰非常适合毕业设计、课程实训或企业固定资产模块二次开发参考。目前已有1116人浏览学习数据库附加即可运行能帮助开发者快速理解ASP.NET多层表单与权限控制的实现思路。1. 这个asp.net固定资产管理系统到底解决什么问题每年到课程设计节点或者小企业想上一套内部管理系统时“asp.net固定资产管理系统”这个zip包总会被反复翻出来。里面装的东西很直白一套能编译运行的asp.net网站源码外加一个数据库备份文件。目标是让固定资产从采购入库、领用借还到折旧报废都有记录可查治的是固定资产管理里最头疼的“账实不符”——账上明明写着这台设备还在实际不知道在谁手里、什么时候借走的、折旧折到哪年了。适合三类人正在找课程设计选题的在校生、要快速交付内部工具的一线开发以及想给现有系统做参考的中小企业IT。技术上不算新但胜在结构完整能跑的代码加上能还原的数据库正好是理解 asp.net 和 SQL Server 怎么配合的最小样本。2. 先拆源码再动手asp.net版本、运行环境与三层架构如何对应拿到 zip 先别急着双击 .sln我一般先做三件事看一眼项目目录结构确认数据库文件是 .bak 还是 .mdf打开 Web.config 看连接字符串。这三件事决定了你后面一小时是在写代码还是在折腾环境。asp.net 是个大筐WebForms 和 MVC 虽然都跑在 System.Web 上但部署位置、路由方式、报错排查路径完全不是一回事第一眼没认准后面全是坑。2.1 一眼识别WebForms还是MVC看入口、页面后缀与路由配置识别方式很简单不用读代码看文件结构就能定。项目里有 Views 和 Controllers 目录还经常带 App_Start 文件夹说明这是一套 asp.net MVC如果看到一堆 .aspx 页面直接躺在根目录或子目录里那就是 WebForms。MVC 页面后缀是 .cshtmlWebForms 是 .aspx这两者一眼就能分开。另外还可以看项目引用里有没有 System.Web.Mvc 程序集有就是 MVC。// App_Start/RouteConfig.cs 里如果能看到这段说明是 asp.net MVC 项目 public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute({resource}.axd/{*pathInfo}); routes.MapRoute( name: Default, url: {controller}/{action}/{id}, defaults: new { controller Home, action Index, id UrlParameter.Optional } ); }这段代码的意思是MVC 项目不直接访问物理文件而是通过 URL 里的 controller/action 路由到对应方法而 WebForms 项目直接访问 Test.aspx 这样的物理页面不需要路由注册表。很多“源码数据库”打包的老系统是 WebForms 写的因为课程设计和内部工具用 WebForms 能快速拖控件出界面而 MVC 的入门门槛更高一点。如果你后续想升级成 asp.net core mvcWebForms 的页面代码不能直接迁移但数据库表结构和 BLL/DAL 业务逻辑基本可以原样复用这是判断版本最值钱的地方。2.2 数据库备份文件如何处理.bak还原和.mdf附加的区别解压后数据库文件常见两种形态一个是 .bak 备份文件一个是 .mdf 加 .ldf 的数据和日志文件。 .bak 需要用 SQL Server 的还原功能重新生成数据库文件适合分发因为它是完整备份 .mdf 可以直接“附加”到实例上但要求 SQL Server 版本不能低于生成这个文件的版本。很多人在这翻车是因为本机装的是 SQL Server 2008而项目里数据库是用 SQL Server 2016 生成的mdf 直接附加不上。内部版本号SQL Server 版本100200811020121202014130201614020171502019附加报错时会给出内部版本号用这个表一查就知道该装哪个版本。动手前先确认当前实例版本在 SSMS 里执行一句最快-- 查看当前 SQL Server 实例的版本号和版本名 SELECT SERVERPROPERTY(ProductVersion) AS ProductVersion, SERVERPROPERTY(Edition) AS Edition;ProductVersion 返回的是一串数字12.x 对应 201413.x 对应 2016对照上面的表就能判断能不能挂。我个人的习惯是如果压缩包里同时给了 .bak 和 .mdf优先用 .bak 还原因为逻辑文件名可以自己指定路径可控如果只有 .mdf那就要保证 SQL Server 版本匹配否则只能换实例或让作者重新导出低版本备份。2.3 连接字符串与三层架构Web.config里那行配置决定整个系统能不能跑这套系统的数据库访问基本都走三层UI 层负责页面展示BLL 层写业务规则DAL 层做数据库增删改查。对新手来说不需要把三层理得多透但要记住所有层的数据库连接都是从一个地方取的就是 Web.config 里的 connectionStrings 节点。这个节点写错整个系统连登录页都进不去。configuration connectionStrings add nameAssetDBConnectionString connectionStringData Source.;Initial CatalogAssetDB;User IDsa;Password你的密码;Integrated Securityfalse providerNameSystem.Data.SqlClient / /connectionStrings /configuration参数说明Data Source. 表示本机默认 SQL Server 实例如果装的 Express 版要写成 .\SQLEXPRESSInitial Catalog 是数据库名字必须和实际还原出来的库名一致Integrated Securitytrue 时用 Windows 身份验证User ID 和 Password 会被忽略适合本地单机调试false 就是用 SQL Server 账号登录部署到别的机器上必须改成目标环境的账号密码。DAL 层读取这行配置的典型动作是这样。using System.Configuration; using System.Data.SqlClient; public static class DbHelper { // 从 Web.config 读取连接字符串全系统共用这一个入口 public static string ConnStr ConfigurationManager .ConnectionStrings[AssetDBConnectionString].ConnectionString; public static SqlConnection GetConnection() { return new SqlConnection(ConnStr); } }这段代码的价值在于集中管理连接以后换数据库地址只改 Web.config 一处不用全项目翻。SqlConnection 默认带连接池同一连接串的开关操作实质是归还和复用连接所以不要担心频繁 new 连接会拖垮数据库真正的问题是很多人忘了用完关闭导致连接池被占满。用 using 包裹或者 finally 里 Close是这个项目里最值得养成的习惯。3. 把源码和数据库跑起来从环境准备到IIS访问的最小路径部署这套系统最少需要四个东西IIS、.NET Framework 4.x、SQL Server、以及源码和数据库文件。版本匹配这事用不着追求最新能跑通就行。我见过不少人直接装最新 Visual Studio 和 SQL Server 2022结果老项目跑不起来因为 .NET Framework 组件没勾全或者数据库兼容级别太新。下面这条路径我反复用过改动最小。3.1 环境匹配清单IIS、.NET Framework、SQL Server版本怎么选先在 Windows 功能里确认 IIS 有没有装。Win10 和 Win11 都自带 IIS 10但默认不装 ASP.NET 4.8 模块这是部署后 500.21 错误的主要来源。以管理员身份打开 PowerShell执行下面的命令一次把 IIS 主服务和 ASP.NET 4.5 扩展装齐。# 以管理员身份运行安装 IIS 全部核心功能 Enable-WindowsOptionalFeature -Online -FeatureName IIS-WebServerRole -All # 安装 ASP.NET 4.8 扩展老项目必需否则页面报 500.19/500.21 Enable-WindowsOptionalFeature -Online -FeatureName IIS-ASPNET45 -AllIIS-ASPNET45 这个功能名在 Windows 10 以后同时覆盖 ASP.NET 4.5 到 4.8 的注册不用手动跑 aspnet_regiis.exe。SQL Server 方面本地开发装 Express 版完全够用关键是要把数据库还原进去。.NET Framework 随系统自带但项目如果是 4.0 目标框架最好确认一下控制面板里“启用或关闭 Windows 功能”中 ASP.NET 4.8 的子项全部勾选这一步最容易漏。3.2 数据库还原实操Management Studio还原与T-SQL脚本拿到 .mdf 文件时用 T-SQL 附加最直白一步到位。拿到 .bak 时先查一下备份里的逻辑文件名再执行还原避免路径和逻辑名对不上报错。下面这段适合只有 .mdf 的情况。-- 附加 mdf 文件路径必须改成你解压后的实际位置 USE [master]; GO CREATE DATABASE AssetDB ON (FILENAME ND:\AssetDB.mdf), (FILENAME ND:\AssetDB_log.ldf) FOR ATTACH; GOFOR ATTACH 会把 .mdf 和 .ldf 作为数据文件和日志文件挂到 SQL Server 上库名 AssetDB 要和 Web.config 里的 Initial Catalog 一致。如果只有 .bak先执行下面的语句看逻辑名再还原。-- 查看备份文件内包含的逻辑文件名 RESTORE FILELISTONLY FROM DISK ND:\AssetDB.bak;查询结果里 LogicalName 列显示的就是 MOVE 后面要写的名字。然后执行还原。-- 还原 .bak 备份REPLACE 允许覆盖同名数据库 RESTORE DATABASE AssetDB FROM DISK ND:\AssetDB.bak WITH REPLACE, MOVE AssetDB TO ND:\AssetDB.mdf, MOVE AssetDB_log TO ND:\AssetDB_log.ldf; GO注意 MOVE 后面单引号里是逻辑名TO 后面是目标物理路径这两个文件要放在 SQL Server 有权限访问的目录最常见的是 SQL Server 默认的 DATA 目录或自己建的 D:\Data。还原成功后茶杯 SSMS 刷新就能看到库然后去对应数据表确认 Users、Assets 等表数据都在再继续部署网站。3.3 IIS部署实操应用程序池、站点绑定与目录权限IIS 里需要建一个独立应用程序池把 .NET CLR 版本指定为 v4.0再把站点物理路径指到源码解压目录。用图形界面点也行但命令行更快下面这是一套我常用的 appcmd 命令。:: 创建应用程序池指定 .NET CLR v4.0托管管道集成 %windir%\system32\inetsrv\appcmd add apppool /name:AssetPool /managedRuntimeVersion:v4.0 /managedPipelineMode:Integrated :: 创建站点物理路径指向源码目录监听 8080 端口 %windir%\system32\inetsrv\appcmd add site /name:AssetSite /physicalPath:D:\asset_web /bindings:http/*:8080: :: 把站点默认应用关联到刚才建的池 %windir%\system32\inetsrv\appcmd set app AssetSite/ /applicationPool:AssetPoolmanagedRuntimeVersion 必须和项目目标框架对应如果项目是老式 .NET Framework 2.0就填 v2.0不确定就先在 Visual Studio 里打开项目属性看目标框架。managedPipelineMode 用 IntegratedWebForms 和 MVC 都能跑Classic 模式只在个别老组件不兼容时才需要换。站点创建后浏览器访问 http://localhost:8080能出现登录页说明部署通了。还有一步不能省给源码目录加上 IIS 运行账户的读写权限尤其是 Uploads、App_Data 这类目录。不加的话账号登录没问题但一上传附件就 500。:: 给上传目录授予 IIS 用户修改权限OI 和 CI 表示对子目录和文件生效 icacls D:\asset_web\uploads /grant IIS_IUSRS:(OI)(CI)M /TIIS_IUSRS 是 IIS 内置账户组M 表示修改权限。如果你在应用程序池里把标识换成了 LocalSystem那权限可以给得更宽但本地调试期不建议够用就行。这一步做完部署就算收尾了。4. 固定资产核心业务台账、借还、折旧的代码与数据库设计跑起来只是第一步真正要改系统时得知道核心业务藏在哪些表里。固定资产管理系统不管界面多花哨业务主线就三块资产台账、借还流转、折旧计提。这三块的代码和表结构也是课程设计和答辩时最常被问的地方。4.1 资产台账表设计每个字段对应一类管理口径资产表通常叫 Assets字段设计要覆盖“这资产是什么、在哪、谁管、值多少”。下面的建表语句是这类系统里常见的骨架。CREATE TABLE Assets ( AssetID INT IDENTITY(1,1) PRIMARY KEY, AssetCode NVARCHAR(50) NOT NULL UNIQUE, -- 资产编码盘点对账靠它 AssetName NVARCHAR(200) NOT NULL, -- 资产名称 CategoryID INT NOT NULL, -- 分类ID联查分类表 Specification NVARCHAR(200) NULL, -- 规格型号 PurchaseDate DATETIME NOT NULL, -- 购置日期 OriginalPrice DECIMAL(18,2) NOT NULL, -- 原值金额精确到分 SalvageRate DECIMAL(5,4) DEFAULT 0.05, -- 残值率默认5% UsefulYears INT DEFAULT 5, -- 使用年限 Status TINYINT DEFAULT 0, -- 状态0在库 1借出 2维修 3报废 DepartmentID INT NULL, -- 当前使用部门 Custodian NVARCHAR(50) NULL, -- 当前保管人 Location NVARCHAR(100) NULL, -- 存放地点 Remark NVARCHAR(500) NULL );AssetCode 必须唯一因为它是资产的“身份证号”盘点时扫的就是这个编码。Status 用 TINYINT 而不是字符串是为了避免状态写错比如“借出”写成“借出中”这种数据污染。金额字段用 DECIMAL(18,2)不要用 float浮点数的精度问题在财务对账时极容易翻车。CategoryID 和 DepartmentID 一般还要配套 Category 和 Department 两张字典表页面下拉框直接查这两张表。借还记录单独放一张表方便以后按时间线追查。CREATE TABLE BorrowReturn ( RecordID INT IDENTITY(1,1) PRIMARY KEY, AssetID INT NOT NULL, -- 关联资产 UserName NVARCHAR(50) NOT NULL, -- 领用人 DepartmentID INT NULL, -- 领用部门 BorrowDate DATETIME NOT NULL DEFAULT GETDATE(), ReturnDate DATETIME NULL, -- 归还日期NULL表示未还 Status TINYINT DEFAULT 0 -- 0借用中 1已归还 );这里 AssetID 建议加外键 REFERENCES Assets(AssetID)课程设计阶段能体现完整性概念。但注意删除资产时得先删借还记录否则外键约束会挡住删除答辩时解释清楚逻辑就行。4.2 借出归还状态流转SQL与C#怎么配合借出流程本质是两步改资产状态为“借出”插入一条借还记录。归还则反过来。这里最容易犯的错是只改资产状态不写记录或者两条 SQL 只执行成功一条导致账实对不上。解决方法是把两步放进一个事务里任何一步失败都整体回滚。-- 第一步把资产从在库改成借出注意 WHERE 里带 Status0 UPDATE Assets SET Status 1, DepartmentID DepartmentID, Custodian Custodian WHERE AssetID AssetID AND Status 0; -- 第二步插入借还记录状态为借用中 INSERT INTO BorrowReturn(AssetID, UserName, DepartmentID, BorrowDate, Status) VALUES(AssetID, UserName, DepartmentID, GETDATE(), 0);WHERE Status0 这一步很关键它保证只有“在库”的资产才能被借出。如果资产已经借给别人UPDATE 影响行数为 0业务层就该抛异常而不是闷头继续插入记录。对应的 C# 代码用 SqlTransaction 把两条命令包起来。public void LendAsset(int assetId, string userName, int deptId) { string sql1 UPDATE Assets SET Status1, DepartmentIDdept, Custodianuser WHERE AssetIDid AND Status0; string sql2 INSERT INTO BorrowReturn(AssetID, UserName, DepartmentID, BorrowDate, Status) VALUES(id, user, dept, GETDATE(), 0); using (SqlConnection conn new SqlConnection(DbHelper.ConnStr)) { conn.Open(); using (SqlTransaction tran conn.BeginTransaction()) { try { using (SqlCommand cmd new SqlCommand(sql1, conn, tran)) { cmd.Parameters.AddWithValue(id, assetId); cmd.Parameters.AddWithValue(dept, deptId); cmd.Parameters.AddWithValue(user, userName); // 影响行数为0说明资产不在“在库”状态直接中止 if (cmd.ExecuteNonQuery() 0) throw new Exception(资产不在在库状态不能借出); } using (SqlCommand cmd new SqlCommand(sql2, conn, tran)) { cmd.Parameters.AddWithValue(id, assetId); cmd.Parameters.AddWithValue(user, userName); cmd.Parameters.AddWithValue(dept, deptId); cmd.ExecuteNonQuery(); } tran.Commit(); } catch { tran.Rollback(); throw; } } } }这段代码是固定资产系统里最常见的数据库增删改查实战写法。要点有三所有数据库操作都从 DbHelper.ConnStr 拿连接所有写操作统一用事务AddWithValue 在项目小、参数少的时候没问题但如果将来做高并发或大数据量建议改成 cmd.Parameters.Add 并显式指定 SqlDbType性能更稳也避免参数类型推断错误。4.3 折旧计算年限平均法的代码实现与参数调整折旧算法很多但课程设计和内部管理系统里年限平均法占绝大多数因为它简单、可解释答辩也好讲。公式是年折旧额 原值 - 残值÷ 使用年限残值 原值 × 残值率。月度折旧额再除以 12。注意金额要精确到分用 decimal 计算别用 double。public decimal GetAccumulatedDepreciation(AssetRow asset, DateTime asOfDate) { // 年限平均法每月折旧固定累计到截止日 decimal salvageValue asset.OriginalPrice * asset.SalvageRate; decimal monthlyDep (asset.OriginalPrice - salvageValue) / asset.UsefulYears / 12m; // 计算已用月数取整数月 int totalMonths (asOfDate.Year - asset.PurchaseDate.Year) * 12 (asOfDate.Month - asset.PurchaseDate.Month); if (totalMonths 0) return 0m; // 超过使用年限不再继续折旧 int maxMonths asset.UsefulYears * 12; if (totalMonths maxMonths) totalMonths maxMonths; return monthlyDep * totalMonths; }参数说明asOfDate 是计算截止日比如盘点报表的日期totalMonths 按自然月差计算不满一个月按一个月算这在简化系统里能接受真要严格按“当月购入当月不提折旧”的会计准则还要再减一个月把判断条件改成 totalMonths - (purchaseDay asOfDate.Day ? 1 : 0)。这个函数适合做列表展示和打印不建议每次写库免得重复累加。真要落库就做一张 DepreciationRecord 表按年批量生成记录每台资产每年一条。5. 部署和使用中的常见坑翻车现场排查实录这章是血泪经验集中营。上面这套流程走下来大概率能跑通但真实环境里总有意外。我按自己踩过的顺序把最常遇到的五个问题列出来每个都按现象、原因、解决三步走帮新人少走弯路。5.1 连不上数据库登录失败和“无法打开数据库”是两回事现象页面报错分成两类一类是“用户 sa 登录失败”另一类是“无法打开登录所请求的数据库”。前者说明账号密码不对或 SQL Server 没开混合认证后者说明库根本没附加成功或者 Web.config 里 Initial Catalog 写错了。原因新手最容易把这两类混为一谈登录失败了一直改 SQL Server 密码结果问题是数据库名错了一个字母。解决先在 SSMS 里用同样的账号密码测试连接确认能进然后用下面这条 SQL 看 sa 是否被禁用。-- 检查 sa 账号是否被禁用is_disabled 为 1 表示禁用 SELECT name, is_disabled FROM sys.sql_logins WHERE name sa;如果 is_disabled1右键 sa 属性把状态改成启用然后重启 SQL Server 服务。接着核对 Web.config 里的 Data Source 和 Initial Catalog确保和 SSMS 里连接的一致。这里有个窍门连接字符串先在 SSMS 的“连接”对话框里按一样的值填一遍SSMS 能连上连接字符串基本就对了。5.2 IIS浏览报500.19或500.21ASP.NET功能没装全现象IIS 里配置完站点浏览器打开直接是 500.19 或 500.21页面内容不清不楚。原因500.19 通常是 Web.config 里的配置块报错常见是缺少 IIS 对应模块500.21 是托管管道模式不对ASP.NET 模块没注册进去。解决先确认第 3 章的两个 PowerShell 命令执行过然后查应用程序池的托管管道模式。:: 查看所有应用程序池的 CLR 版本和托管管道模式 %windir%\system32\inetsrv\appcmd list apppool /text:name,managedRuntimeVersion,managedPipelineMode如果 ManagedPipelineMode 显示 Classic而项目是 MVC改成 Integrated如果 managedRuntimeVersion 是 v2.0项目目标框架是 4.x就改成 v4.0。改完重启站点再试。还不行就打开“启用或关闭 Windows 功能”把“.NET Framework 4.8”下所有子项勾满多数情况是这里少了 HTTP 激活相关的组件。5.3 上传的图片附件找不到虚拟路径与写权限现象附件上传提示成功但页面上图片不显示F12 看请求路径 404或者换台电脑部署以前上传的文件全不见了。原因代码里用了相对路径比如 Server.MapPath(~/Uploads/)但 Uploads 目录的物理位置被写死在别的盘或者站点目录根本没有 IIS 用户的写权限。解决先确认上传目录在项目根目录下且物理路径正确再给目录授权。:: 给上传目录授予 IIS 用户修改权限OI 和 CI 让权限继承到所有子项 icacls D:\asset_web\uploads /grant IIS_IUSRS:(OI)(CI)M /T注意这里的 M 是修改权限包含写入和删除。如果目录在 C 盘 Program Files 下IIS 用户经常没有写权限建议直接把站点目录放到 D 盘或非系统盘省去一堆权限审批问题。数据库里存的是相对路径如 /Uploads/xxx.png页面就要用相对路径拼别把盘符绝对路径写进数据库否则换机器必翻车。5.4 初始账号密码进不去密码加密方式与账号重置现象登录页能打开但默认账号密码进不去或者数据库还原后原作者的密码因为环境变了而登录失败。原因很多系统的 Users 表密码字段不是明文而是 MD5 或 SHA1 加盐后的结果。网上流传的默认密码常被改过或者代码里加密方式和你抄的 SQL 对不上。解决先用 SSMS 直接查 Users 表确认账号存在和密码字段的样子。-- 查看用户表数据弄清密码字段是明文还是加密串 SELECT UserID, UserName, Password FROM Users;如果 Password 列显示一长串 32 位十六进制基本就是 MD5。这时直接 UPDATE 成明文是没用的因为登录时代码还会再加密一次并比对。正确做法是找到代码里的加密函数用同样的方式生成新密码串再写库。如果代码用的是 FormsAuthentication.HashPasswordForStoringInConfigFile(password, MD5)你可以自己在 C# 里跑一段生成结果后 UPDATE 进去或者直接在数据库里用 HashBytes 生成但要注意编码一致。5.5 中文乱码和数据对不上编码不一致导致的黑匣子现象页面显示中文变成问号或乱码导出 Excel 中文内容也乱有时候用户名字段显示正常资产名称乱码。原因页面文件编码、数据库排序规则、请求响应编码三者不一致最常见的是源码文件是 GB2312 保存的而 Web.config 强制了 UTF-8或者反过来。解决先看页面顶部 charset 声明和 Web.config 里的 globalization 设置让三者统一。system.web !-- 统一请求和响应编码老项目如果源码是 GB2312把 utf-8 改成 gb2312 -- globalization requestEncodingutf-8 responseEncodingutf-8 fileEncodingutf-8 / /system.web参数说明requestEncoding 管接收参数解析responseEncoding 管输出页面编码fileEncoding 管 .aspx 文件本身解析。如果源码文件本身是 GB2312只改这里是不够的还得把文件另存为 UTF-8。数据库排序规则建议用 Chinese_PRC_CI_AS这个在还原数据库的时候一般会跟着备份走但如果新建库就要在创建时指定否则字段排序和比较可能出现“中文不相等但显示一样”的玄学问题。6. 拿到源码后最值得做的三个改造导出、扫码、权限收口系统跑通后别急着加花哨功能。我从过往经验里挑三个改动小、收益大的方向导出 Excel、扫码盘点、权限收口。这三个做完这套系统基本能从小作业变成能日常用的工具。6.1 用NPOI导出Excel资产台账很多课程设计做导出是用 Response.Write 拼 CSV 或 HTML 表格能出文件但格式一塌糊涂Excel 打开还会告警。换成 NPOI导出的 xlsx 干净可控是最值得先做的改造。using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; public void ExportAssets(DataTable dt, string path) { // XSSFWorkbook 对应 .xlsx适合 Office 2007 以上 IWorkbook workbook new XSSFWorkbook(); ISheet sheet workbook.CreateSheet(固定资产台账); for (int i 0; i dt.Rows.Count; i) { IRow row sheet.CreateRow(i); row.CreateCell(0).SetCellValue(dt.Rows[i][AssetCode].ToString()); row.CreateCell(1).SetCellValue(dt.Rows[i][AssetName].ToString()); row.CreateCell(2).SetCellValue(dt.Rows[i][CategoryName].ToString()); } using (FileStream fs new FileStream(path, FileMode.Create, FileAccess.Write)) { workbook.Write(fs); } }这段代码把 DataTable 写入 xlsx第一行是数据而不是表头正式用的时候在第一行加一行列名。反向操作也一样可行用同样思路解析 Excel 导入数据库批量初始化资产台账比手动一条条录入强太多。NPOI 在项目里用 NuGet 安装注意 XSSFWorkbook 对应 xlsxHSSFWorkbook 对应 .xls别选错格式。6.2 盘点场景用条码辅助核对固定资产管理最核心的诉求是盘点对账。与其让人拿着打印表格一行行比对不如给每个资产生成条形码或二维码贴在设备上。盘点时用扫码枪扫 AssetCode系统自动跳到该资产详情直接勾选“已盘到”比手工录入快出一个量级。生成条码别自己写算法用 ZXing.Net 或 BarcodeLib 这类现成库核心思路是把 AssetCode 渲染成图片存到 Uploads/Barcodes 目录报表打印时拼到表格里。这一步不需要改数据库只加一个列表页和扫码入口工作量半天左右。6.3 按角色收口权限避免一套账号走天下老项目最让人不放心的是权限。登录后无论谁也都能删资产、改折旧率。最小改造方案是登录时把角色名存进 Session 或 FormsAuthentication Ticket然后在资产新增、删除按钮的点击事件里判断角色管理员才能执行普通用户只读。更进一步可以在 Web.config 里对 Admin 目录配置 authorization匿名用户直接挡在目录外。configuration location pathAdmin system.web authorization !-- 只允许 Admin 角色访问 Admin 目录 -- allow rolesAdmin / deny users* / /authorization /system.web /location /configuration这套配置的好处是权限控制在 IIS 层就生效连页面资源文件都能挡住。如果这套系统要长期用我强烈建议把这三件事排在所有新功能前面。我自己的教训是当年接手一套别人写的资产系统功能很全但权限裸奔结果实习生随手把报废资产的数据删了恢复花了一整天。从那以后我拿到任何“源码数据库”的项目第一件事永远是把权限和备份补齐再谈功能。固定资产管理系统要的是稳定可追溯不是功能多炫。希望帮到你。本文还有配套的精品资源点击获取