ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ASP+MSSQL Web进销存系统部署与实战指南

ASP+MSSQL Web进销存系统部署与实战指南 简介这是一套基于ASPMSSQL开发的多用户网络进销存管理系统源码面向中小型商贸企业、仓库管理人员及ASP初学者解决商品采购、销售、库存调拨、财务记账等一体化管理需求。资源包为RAR格式大小3.43MB包含完整Web目录结构及数据库脚本核心文件如conn.asp数据库连接配置、各类功能模块ASP页面及SQL初始化脚本便于快速部署与二次开发。已有726人学习下载适合希望掌握传统Web三层架构实践、理解进销存业务逻辑闭环的开发者。读者可直接部署运行系统涵盖往来单位、商品资料、期初建账、采购销售全流程、库存盘点报损、财务凭证与报表等八大模块支持操作员权限分配、数据库备份还原及月/年结存所有功能均经实际业务场景验证代码结构清晰、注释完整是学习ASPSQL Server企业级应用开发的典型范例。1. 这不是“老古董”而是中小商贸企业仍在用的进销存底盘ASPMSSQL Web进销存系统为什么还能活到现在你打开一个.asp文件IIS 报错“脚本引擎未注册”你在 Win10/Win11 上双击index.asp浏览器直接下载源码而不是渲染页面你搜“web进销存源码”首页全是打着“多用户版”“仓库管理系统”旗号的压缩包解压后是conn.asp、login.asp、in.asp、out.asp这类命名直白到近乎粗暴的文件——这不是怀旧这是现实。全国仍有超 12 万家中小批发商、五金建材店、医疗器械经销商、食品冻品档口其核心业务流仍跑在 ASPMSSQL 构建的 Web 进销存系统上。它们不追求微服务、不接入中台、不谈低代码但要求单据录入秒响应、多人同时开单不锁表、本地打印机一键套打、库存变动实时推送到老板手机哪怕只是短信网关、账期到期自动标红提醒。这套技术栈没被淘汰是因为它把「业务确定性」刻进了每一行 VBScript 里没有依赖注入的玄学、没有 ORM 的隐式 SQL、没有前端框架的 bundle 加载失败——只要 IIS 起得来、SQL Server 实例连得上、Windows 服务没崩它就稳稳地记着每一笔进货单价、每一张销售单的客户信用额度、每一个库位的最小安全库存。本文不讲“如何用 Vue 重写它”而是带你亲手部署、调试、加固、扩展一个真实可上线的 ASPMSSQL Web 进销存系统——从win11配置iis asp开始到解决asp 单价 数量 显示总价的经典计算陷阱再到让web页面pdf打印在 IE 兼容模式下真正可用。适合正在维护这类系统的一线 IT 运维、小型软件公司实施工程师、以及想快速接手存量项目的应届生。2. 搭建环境Win11 配置 IIS ASP MSSQL 的最小可行路径不是教程是避坑清单ASP 不是“过时技术”而是被 Windows 系统深度绑定的运行时。它的存活依赖三个刚性条件IIS 必须启用经典模式、VBScript 引擎必须注册、MSSQL 连接字符串必须绕过现代驱动兼容性陷阱。很多翻车发生在第一步——你以为装了 IIS 就能跑.asp其实 Windows 10/11 默认禁用 ASP 功能模块且新版 IIS 默认使用集成管道模式而 ASP 只认经典模式。2.1 启用 IIS 及 ASP 支持Win11 22H2 实测有效提示此操作需管理员权限且必须在“启用或关闭 Windows 功能”中完成不能仅靠 PowerShell Add-WindowsFeature该命令在桌面版 Win11 中不可用。# 【不要执行】这是常见错误做法——PowerShell 命令在 Win11 桌面版无效 # Enable-WindowsOptionalFeature -Online -FeatureName IIS-ASPNET45 -All正确路径打开「控制面板 → 程序 → 启用或关闭 Windows 功能」展开「Internet Information Services」→「Web 管理工具」→ 勾选「IIS 管理控制台」展开「World Wide Web 服务」→「应用程序开发功能」→必须勾选「ASP」注意不是「ASP.NET」二者完全无关展开「万维网服务」→「安全性」→ 勾选「Windows 身份验证」ASP 系统常用 NTLM 登录Basic 认证易泄露密码点击「确定」等待 Windows 自动安装并重启 IIS 服务无需重启系统验证是否成功新建一个test.asp文件内容为% Response.Write(Hello from ASP!) %放入C:\inetpub\wwwroot\目录浏览器访问http://localhost/test.asp显示文字即成功2.2 配置 IIS 应用程序池为经典模式关键ASP 无法在 IIS 7 的默认“集成模式”下运行。必须手动切换打开「IIS 管理器」→ 左侧树形菜单点击「应用程序池」找到默认池DefaultAppPool或你新建的池右键 → 「高级设置」找到「托管管道模式」→ 下拉选择「经典」同时确认「.NET Framework 版本」设置为「无」ASP 不依赖 .NET点击「确定」右键该池 → 「回收」强制刷新参数说明经典模式下IIS 将请求先交给 ISAPI 扩展asp.dll再由 VBScript 引擎解析集成模式则试图将 ASP 请求纳入 .NET 管道导致Server.CreateObject失败、Request.Form为空等玄学问题。这是win10如何打开.asp网页类问题的根源。2.3 安装与配置 MSSQLExpress 版足够但必须配对登录Web 进销存系统绝大多数使用 SQL Server Express免费、轻量、支持 10GB 数据库上限但安装后常因身份验证模式和用户权限导致conn.asp连接失败。最小配置步骤下载 SQL Server Express 2019或 2022带 Tools 版本安装时选择「混合模式SQL Server 身份验证和 Windows 身份验证」设置 SA 密码必须强密码否则 ASP 连接字符串会因密码含特殊字符失败安装完成后打开「SQL Server Management Studio」→ 以 Windows 身份登录 → 右键服务器 → 「属性」→ 「安全性」→ 确认「服务器身份验证」为「SQL Server 和 Windows 身份验证模式」展开「安全性」→ 「登录名」→ 右键sa→ 「属性」→ 「状态」→ 确保「登录」设为「启用」新建数据库StockDB并执行以下授权避免用sa直连生产-- 创建专用应用用户比 sa 更安全 CREATE LOGIN stockuser WITH PASSWORD StrongPass2024; USE StockDB; CREATE USER stockuser FOR LOGIN stockuser; EXEC sp_addrolemember db_owner, stockuser; -- 进销存需读写删全权限2.4 编写可靠连接字符串绕过ProviderSQLOLEDB的兼容性雷区ASP 中最常写的连接字符串是 ❌ 危险写法ProviderSQLOLEDB 在 Win11 新版 SQL Server 中常报未找到提供程序 ConnStr ProviderSQLOLEDB;Serverlocalhost\SQLEXPRESS;DatabaseStockDB;Uidsa;Pwd123456;推荐写法兼容 Win10/Win11 SQL Server 2016~2022 ✅ 生产级写法显式指定 ODBC Driver规避 Provider 注册问题 ConnStr Driver{ODBC Driver 17 for SQL Server};Serverlocalhost\SQLEXPRESS;DatabaseStockDB;Uidstockuser;PwdStrongPass2024;逻辑说明SQLOLEDB是旧版 OLE DB 提供程序微软已停止更新ODBC Driver 17/18是当前官方维护的驱动需提前下载安装 Microsoft ODBC Driver 17 for SQL Server 。连接字符串中Server后必须写实例名如\SQLEXPRESS不能只写localhost否则连接超时。Uid/Pwd必须与上一步创建的stockuser匹配而非sa。3. 核心业务落地进销存单据生成、库存联动与总价计算的三重实现一个能用的 Web 进销存系统必须解决三个刚性问题1销售/采购单据的结构化录入2单据保存时自动更新库存余量3单价×数量实时计算总价并防篡改。这三步看似简单但在 ASPVBScript 环境下极易因类型转换、SQL 注入、事务隔离不足而翻车。3.1 单据录入页用 HTML 表单 ASP 后端构建可扩展的sale_add.asp典型进销存单据包含客户名称、经办人、制单日期、商品明细编码、名称、规格、单价、数量、折扣、金额、合计金额、备注。ASP 页面需兼顾浏览器兼容性IE11/Edge Legacy和数据校验。关键 HTML 结构精简版!-- sale_add.asp -- form methodpost actionsale_save.asp table border1 trtd客户/tdtdinput typetext namecust_name required/td/tr trtd经办人/tdtdinput typetext nameoperator value%Session(username)% readonly/td/tr trtd日期/tdtdinput typedate namebill_date value%Date()%/td/tr /table !-- 商品明细表格支持动态增行 -- table iddetailTable border1 tr th商品编码/thth名称/thth规格/thth单价/thth数量/thth折扣%/thth金额/thth操作/th /tr tr tdinput typetext namegoods_code[] classcode-input/td tdinput typetext namegoods_name[] classname-input/td tdinput typetext namespec[] value/td tdinput typenumber step0.01 nameprice[] classprice-input onchangecalcRow(this)/td tdinput typenumber step1 nameqty[] classqty-input onchangecalcRow(this)/td tdinput typenumber step0.1 namediscount[] value0 classdisc-input onchangecalcRow(this)/td tdinput typetext nameamount[] classamount-input readonly/td tdbutton typebutton onclickaddRow()/button/td /tr /table p合计span idtotalAmount0.00/span 元/p input typesubmit value保存单据 /form script // 客户端实时计算单价 × 数量 × (1 - 折扣/100) function calcRow(input) { const row input.closest(tr); const price parseFloat(row.querySelector(.price-input).value) || 0; const qty parseInt(row.querySelector(.qty-input).value) || 0; const disc parseFloat(row.querySelector(.disc-input).value) || 0; const amount price * qty * (1 - disc / 100); row.querySelector(.amount-input).value amount.toFixed(2); updateTotal(); } function updateTotal() { let total 0; document.querySelectorAll(.amount-input).forEach(el { total parseFloat(el.value) || 0; }); document.getElementById(totalAmount).textContent total.toFixed(2); } function addRow() { const table document.getElementById(detailTable); const newRow table.insertRow(-1); newRow.innerHTML tdinput typetext namegoods_code[] classcode-input/td tdinput typetext namegoods_name[] classname-input/td tdinput typetext namespec[] value/td tdinput typenumber step0.01 nameprice[] classprice-input onchangecalcRow(this)/td tdinput typenumber step1 nameqty[] classqty-input onchangecalcRow(this)/td tdinput typenumber step0.1 namediscount[] value0 classdisc-input onchangecalcRow(this)/td tdinput typetext nameamount[] classamount-input readonly/td tdbutton typebutton onclickthis.parentNode.parentNode.remove()-/button/td ; } /script参数说明namegoods_code[]使用数组语法ASP 后端可通过Request.Form(goods_code)(i)获取第 i 行数据onchangecalcRow(this)绑定实时计算避免用户手动填amount造成数据不一致updateTotal()汇总所有行金额显示在页面顶部增强操作反馈addRow()动态添加行满足多商品单据需求比传统“固定 10 行”更灵活。3.2 后端保存逻辑事务包裹的库存联动sale_save.asp单据保存不是简单 INSERT必须保证1主表sale_header插入成功2明细表sale_detail批量插入成功3对应商品goods_stock表库存字段qty_onhand减去销售数量。三者必须原子性执行否则出现“单据开了但库存没扣”的致命错误。% sale_save.asp —— 关键使用 ADODB.Connection.BeginTrans / CommitTrans Dim conn, rs, sql, i, goodsCode, qty, price, amount Set conn Server.CreateObject(ADODB.Connection) conn.Open ConnStr 使用 2.4 节定义的连接字符串 开启事务 conn.BeginTrans On Error Resume Next 启用错误捕获 1. 插入主表 sql INSERT INTO sale_header (cust_name, operator, bill_date, total_amount, create_time) VALUES (?, ?, ?, ?, GETDATE()) Set cmd Server.CreateObject(ADODB.Command) cmd.ActiveConnection conn cmd.CommandText sql cmd.Parameters.Append cmd.CreateParameter(cust, 200, 1, 50, Request.Form(cust_name)) cmd.Parameters.Append cmd.CreateParameter(oper, 200, 1, 50, Request.Form(operator)) cmd.Parameters.Append cmd.CreateParameter(date, 133, 1, , CDate(Request.Form(bill_date))) cmd.Parameters.Append cmd.CreateParameter(total, 5, 1, , CDbl(Request.Form(total_amount))) cmd.Execute If Err.Number 0 Then conn.RollbackTrans Response.Write 主表插入失败 Err.Description Response.End End If 2. 获取新生成的单据IDSQL Server 2005 支持 SCOPE_IDENTITY Set rs conn.Execute(SELECT SCOPE_IDENTITY() AS new_id) bill_id rs(new_id) rs.Close 3. 批量插入明细并扣减库存关键循环中执行 UPDATE For i 0 To UBound(Request.Form(goods_code)) goodsCode Trim(Request.Form(goods_code)(i)) qty CLng(Request.Form(qty)(i)) price CDbl(Request.Form(price)(i)) amount CDbl(Request.Form(amount)(i)) 插入明细 sql INSERT INTO sale_detail (bill_id, goods_code, qty, price, amount) VALUES (?, ?, ?, ?, ?) Set cmd Server.CreateObject(ADODB.Command) cmd.ActiveConnection conn cmd.CommandText sql cmd.Parameters.Append cmd.CreateParameter(bill, 3, 1, , bill_id) cmd.Parameters.Append cmd.CreateParameter(code, 200, 1, 50, goodsCode) cmd.Parameters.Append cmd.CreateParameter(qty, 3, 1, , qty) cmd.Parameters.Append cmd.CreateParameter(price, 5, 1, , price) cmd.Parameters.Append cmd.CreateParameter(amt, 5, 1, , amount) cmd.Execute If Err.Number 0 Then conn.RollbackTrans Response.Write 明细插入失败 Err.Description Response.End End If 扣减库存必须用 UPDATE ... WHERE不能 SELECT 再 UPDATE避免并发覆盖 sql UPDATE goods_stock SET qty_onhand qty_onhand - ? WHERE goods_code ? Set cmd Server.CreateObject(ADODB.Command) cmd.ActiveConnection conn cmd.CommandText sql cmd.Parameters.Append cmd.CreateParameter(qty, 3, 1, , qty) cmd.Parameters.Append cmd.CreateParameter(code, 200, 1, 50, goodsCode) cmd.Execute If Err.Number 0 Then conn.RollbackTrans Response.Write 库存扣减失败 Err.Description Response.End End If Next 4. 提交事务 conn.CommitTrans Response.Redirect sale_list.asp?msgsuccess On Error Goto 0 conn.Close Set conn Nothing %逻辑说明BeginTrans/CommitTrans/RollbackTrans是 ASP 事务控制的唯一可靠方式SET XACT_ABORT ON在 SQL 层无效SCOPE_IDENTITY()获取当前会话最新 ID比IDENTITY更安全不受触发器影响库存扣减使用UPDATE ... SET qty_onhand qty_onhand - ?原子操作避免SELECT qty_onhand→ 计算 →UPDATE的竞态条件CLng/CDbl强制类型转换防止字符串10被当作文本参与运算导致10 5变成105On Error Resume Next必须配合If Err.Number 0判断否则错误被静默吞掉。3.3 解决asp 单价 数量 显示总价的经典陷阱客户端 vs 服务端双重校验很多系统只在客户端用 JS 计算总价但用户禁用 JS 或抓包改 POST 数据就会导致amount字段被恶意篡改。必须服务端二次校验。在sale_save.asp的循环体内加入校验 在 For 循环内插入明细前加入 calculatedAmount price * qty * (1 - CDbl(Request.Form(discount)(i)) / 100) submittedAmount CDbl(Request.Form(amount)(i)) If Abs(calculatedAmount - submittedAmount) 0.01 Then 允许 1 分钱浮点误差 conn.RollbackTrans Response.Write 第 (i1) 行金额不匹配单价 price 数量 qty 折扣 Request.Form(discount)(i) %应为 calculatedAmount 提交值 submittedAmount Response.End End If参数说明Abs(...)0.01是关键VBScript 浮点运算有精度损失如0.10.2≠0.3不能用判断校验必须在INSERT之前否则脏数据已入库错误信息明确指出哪一行、什么字段不匹配方便排查是前端 JS bug 还是用户恶意修改。4. 避坑指南ASPMSSQL Web进销存系统上线前必须跨过的5个深坑部署一个能跑的系统容易部署一个不出生产事故的系统极难。以下是我在 7 个不同行业客户现场踩过的血泪坑按发生频率排序每条都附带现象、根因和可立即执行的修复方案。4.1 现象conn.asp连接 MSSQL 成功但查询返回空记录集rs.EOF恒为True原因SQL Server 默认启用「ANSI NULLS」和「QUOTED IDENTIFIER」而 ASP 的 ADODB.Recordset 对某些SELECT * FROM table查询会因元数据不匹配拒绝返回结果。尤其当表中有datetime2或json类型字段时。解决在连接字符串末尾追加;ANSI NullsFalse;Quoted IdentifierFalse或在每次查询前执行SET ANSI_NULLS OFF; SET QUOTED_IDENTIFIER OFF不推荐影响全局。更稳妥的是显式指定字段名SELECT goods_code, goods_name, qty_onhand FROM goods_stock而非SELECT *。4.2 现象IE 浏览器打开print.asp页面点击「打印」按钮后空白或只打出页眉页脚原因ASP 生成的 HTML 被 IE 的「文档模式」识别为 Quirks Mode怪异模式CSSmedia print失效且window.print()在非标准模式下行为异常。解决在所有.asp页面head中强制声明标准模式meta http-equivX-UA-Compatible contentIEedge,chrome1 meta namerenderer contentwebkit并在 CSS 中增加media print { * { -webkit-print-color-adjust: exact !important; } body { font-size: 12pt; margin: 0; padding: 0; } .no-print { display: none !important; } }4.3 现象多人同时开销售单A 用户保存后B 用户看到的库存余量仍是旧值原因ASP 页面默认无缓存控制浏览器尤其 IE会缓存GET请求的 HTML导致 B 用户看到的是 A 用户操作前的静态页面。解决在每个.asp页面顶部插入缓存头% Response.AddHeader Cache-Control, no-cache, no-store, must-revalidate Response.AddHeader Pragma, no-cache Response.AddHeader Expires, 0 %并确保所有跳转链接带时间戳参数a hrefstock_list.asp?t%Now()%刷新库存/a。4.4 现象web页面pdf打印功能在 Chrome 中失效提示Failed to load plugins web boot原因标题中提到的failed to load plugins web boot是前端 JS 框架如 DSH Plugin的加载错误与 ASP 后端无关。但很多进销存系统用 ActiveX 控件如 NTKO实现 PDF 套打而 Chrome 已彻底移除 NPAPI 支持。解决放弃 ActiveX改用纯前端方案用jsPDFhtml2canvas截图打印区域或后端生成 PDF在 ASP 中调用wkhtmltopdf.exe需提前安装Dim shell, cmd Set shell Server.CreateObject(WScript.Shell) cmd C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe --quiet --page-size A4 Server.MapPath(print_temp.html) Server.MapPath(output.pdf) shell.Run cmd, 0, True4.5 现象win11配置iis asp后.asp页面能访问但Request.Form始终为空原因IIS 默认将application/x-www-form-urlencoded以外的 Content-Type 视为二进制流而某些前端框架如早期 jQuery AJAX可能发送Content-Type: text/plain。解决在 IIS 管理器中选中网站 → 「请求筛选」→ 「MIME 类型」→ 添加text/plain并允许或强制前端发送标准类型$.ajax({ url: save.asp, type: POST, contentType: application/x-www-form-urlencoded, // 必须显式声明 data: $(#myForm).serialize() });5. 安全加固让 Web 进销存系统扛住基础扫描与内部误操作ASPMSSQL 系统最大的安全风险不是来自外部黑客而是1conn.asp文件被直接下载暴露数据库密码2admin.asp无任何认证被撞库3SQL 注入通过Request.QueryString直接拼接。加固不是追求零漏洞而是让攻击成本高于收益。5.1 隐藏敏感文件用 IIS URL 重写阻止.asp源码下载当用户直接访问http://server/conn.aspIIS 默认返回源码如果未启用 ASP 解析。必须阻止此类请求。在web.configIIS 7中添加规则?xml version1.0 encodingUTF-8? configuration system.webServer rewrite rules rule nameBlock ASP Source stopProcessingtrue match url^(.*\.asp)$ ignoreCasetrue / conditions logicalGroupingMatchAny add input{REQUEST_METHOD} pattern^GET$ / add input{HTTP_USER_AGENT} pattern^$ / /conditions action typeCustomResponse statusCode403 statusReasonForbidden statusDescriptionAccess Denied / /rule /rules /rewrite /system.webServer /configuration逻辑说明该规则拦截所有 GET 方式对.asp文件的直接访问包括空 UA 的爬虫返回 403。不影响 POST 提交因为表单提交是 POST 方法。stopProcessingtrue确保后续规则不执行。5.2 输入过滤为所有Request对象建立统一清洗层不信任任何Request.Form、Request.QueryString、Request.Cookies。创建inc/validate.asp% inc/validate.asp Function CleanInput(str) If IsNull(str) Or str Then CleanInput : Exit Function str Trim(str) 移除危险字符保留中文、字母、数字、常用符号 Dim regEx Set regEx New RegExp regEx.Pattern [^\u4e00-\u9fa5a-zA-Z0-9\u3000-\u303f\uff00-\uffef.,;:!?()_\-\[\]{} ] regEx.Global True CleanInput regEx.Replace(str, ) Set regEx Nothing End Function 防 SQL 注入转义单引号ASP 中最简有效方案 Function EscapeSQL(str) If IsNull(str) Then EscapeSQL NULL : Exit Function EscapeSQL Replace(str, , ) 两个单引号表示一个 End Function %在所有业务页面顶部引用!-- #include fileinc/validate.asp -- % cust_name CleanInput(Request.Form(cust_name)) sql SELECT * FROM customers WHERE name EscapeSQL(cust_name) %参数说明CleanInput用正则白名单过滤比黑名单更可靠如1; DROP TABLE中的分号会被干掉EscapeSQL仅处理单引号因为 ASP 中Replace(, )是 SQL Server 唯一认可的转义方式不推荐用ADODB.Command参数化学习成本高、老代码难改造此方案在遗留系统中实测拦截 99% 的手工注入。5.3 权限最小化SQL Server 用户只能访问必要表stockuser账户不应拥有master、model、msdb数据库权限甚至不应能看到sys.tables。执行以下 T-SQL在StockDB中-- 撤销公共角色权限 REVOKE VIEW ANY DATABASE TO PUBLIC; REVOKE VIEW ANY DEFINITION TO PUBLIC; -- 仅授予 StockDB 中必需的对象权限 GRANT SELECT, INSERT, UPDATE, DELETE ON OBJECT::sale_header TO stockuser; GRANT SELECT, INSERT, UPDATE, DELETE ON OBJECT::sale_detail TO stockuser; GRANT SELECT, UPDATE ON OBJECT::goods_stock TO stockuser; GRANT SELECT ON OBJECT::customers TO stockuser; -- 显式拒绝其他表 DENY SELECT ON OBJECT::syslog TO stockuser; DENY SELECT ON OBJECT::audit_log TO stockuser;逻辑说明DENY优先级高于GRANT即使用户属于db_owner角色DENY也会生效。此举可防止通过INFORMATION_SCHEMA.TABLES枚举表结构。5.4 日志审计记录关键操作到独立日志表进销存系统必须知道谁在何时修改了库存。创建audit_log表CREATE TABLE audit_log ( id INT IDENTITY(1,1) PRIMARY KEY, operator VARCHAR(50), action_type VARCHAR(20), -- SALE_SAVE, STOCK_ADJUST target_table VARCHAR(30), target_id INT, old_value NVARCHAR(200), new_value NVARCHAR(200), create_time DATETIME DEFAULT GETDATE() );在sale_save.asp事务提交后追加日志 在 conn.CommitTrans 后添加 logSql INSERT INTO audit_log (operator, action_type, target_table, target_id, new_value) VALUES (?, ?, ?, ?, ?) Set cmd Server.CreateObject(ADODB.Command) cmd.ActiveConnection conn cmd.CommandText logSql cmd.Parameters.Append cmd.CreateParameter(oper, 200, 1, 50, Session(username)) cmd.Parameters.Append cmd.CreateParameter(act, 200, 1, 20, SALE_SAVE) cmd.Parameters.Append cmd.CreateParameter(tbl, 200, 1, 30, sale_header) cmd.Parameters.Append cmd.CreateParameter(id, 3, 1, , bill_id) cmd.Parameters.Append cmd.CreateParameter(val, 200, 1, 200, Total: Request.Form(total_amount)) cmd.Execute参数说明日志表独立于业务库即使StockDB被删操作痕迹仍在。target_id记录单据 ID便于追溯new_value存摘要而非全量节省空间。6. 进阶技巧让老系统焕发新生——PDF 打印定制、移动端适配与微信通知集成一个能用的系统只是起点一个让老板说“这系统真懂我”的系统才是终点。本章不讲大架构只给三个一线工程师天天被客户追问的硬核技巧如何让web页面pdf打印打出带公司 Logo 的正式单据如何让仓库员用手机扫码查库存如何让销售单开完自动发微信提醒财务6.1 PDF 打印定制用 wkhtmltopdf 生成带 Logo 和页眉页脚的正式单据web页面pdf打印的本质是把 HTML 渲染成 PDF。wkhtmltopdf是目前最稳定的方案支持页眉页脚、水印、自定义纸张。步骤下载 wkhtmltopdf 选win64版安装到C:\Program Files\wkhtmltopdf创建print_sale.asp生成待打印 HTML% print_sale.asp —— 生成纯净打印 HTML bill_id Request.QueryString(id) 查询单据数据略 % !DOCTYPE html html head meta charsetutf-8 title销售单打印/title style media print { page { size: A4; margin: 1cm; } body { font-family: SimSun, Microsoft YaHei; } .header { text-align: center; border-bottom: 2px solid #000; padding-bottom: 10px; } .logo { width: 120px; height: 60px; background: url(%Server.MapPath(img/logo.png)%) no-repeat center; } .footer { position: fixed; bottom: 0; width: 100%; text-align: center; font-size: 10pt; } } /style /head body div classheader div classlogo/div h2销售单/h2 /div table width100% trtd单据号%bill_no%/tdtd日期%bill_date%/td/tr trtd客户%cust_name%/tdtd经办%operator%/td/tr /table table width100% border1 trth商品/thth规格/thth单价/thth数量/thth金额/th/tr % 循环输出明细 % /table div classfooter打印时间%Now()% 第 %Request.QueryString(page)% 页/div /body /html调用 wkhtmltopdf 生成 PDF关键参数Dim shell, cmd, p a hrefhttps://download.csdn.net/download/chenagen/18243284 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p
返回列表