ARTICLE · 1032662
一个 Excel 表格折磨了整个部门,我用一个网址终结了它
——把网页搬进公司 NAS 的全过程,以及我踩过的 4 个坑
一、那个让人眼花的下午
上周五下午四点,我路过财务部,看见小杨正对着屏幕一个一个数。
屏幕上是一张采购清单,几百行。每一行都有一列"货品规格",里面是些这样的内容:
1350*800*600 1200*1000*800mm 1.2*0.8*0.6m L1350*W800*H600她要做的事,是把这些数字拆成长、宽、高,算出木箱的表面积,再乘以单价和数量,得出成本金额。
"这个你手算?"我问。
"不然呢,"她头也没抬,"规格写法还不一样,有的是毫米,有的是米,有的还带字母 LWH,有的还写个'出口'。我得一个个看清楚。"
我站在那儿看了三分钟。三分钟,她算了四行。
按这个速度,几百行得算到明天。但比慢更麻烦的是另一件事——
算错了,没人知道。
一个 1350 看成 13500,一个"出口"漏看了,成本就差出去一截。而这几百行数字,最后是要拿去报价的。
我说:"你把这个表发我一份,我试试。"
二、两百行代码,能顶三个人
我把表格拿回工位,没有马上写代码。我先想了一个问题:
这件事的本质是什么?
不是"算平方"——平方公式谁都会。真正的麻烦在三件事:
- 格式不统一
:毫米、米、带单位、带字母前缀,人眼能分辨,公式不行。 - 规则要判断
:品名里带"出口"的走国外价,不带的走国内价。 - 结果要写回原表
:算完还得贴回去,不能只给个数字。
想清楚这三点,我就知道该找谁了——这种"规则明确、重复劳动"的活,正是 AI 最擅长的。
我把表头截图发给 AI 助手,描述了一遍需求,十分钟后拿到了一个 HTML 文件。
打开它,界面朴素得有点简陋:一个虚线框,写着"点击选择文件或拖拽到这里"。
我把那张表拖进去。
两秒后,浏览器自动下载了一个新文件。打开一看,原表最右边多出七列:
几百行,两秒。
而且这里有个关键设计:数据不出本机。
这个页面没有后端,不联网上传,Excel 的解析全在你自己电脑的浏览器里完成。对财务数据来说,这一条比什么都重要——你不需要向任何人解释"我把公司数据传到哪里去了"。
小杨试了一遍,眼睛亮了:"这个好快。"
然后她问了一句让事情变复杂的话:
"我能发给其他同事用吗?"
三、把文件发出去,麻烦才刚开始
我一开始想得很简单:把 HTML 文件发微信群里不就行了?
试了两天,现实给了我一记耳光。
问题一:有人不会用。 双击打开是没错,但有人用 WPS 打开、有人存到了下载文件夹再找不到、有人问"这个是不是要联网"。
问题二:版本会乱。 我改了一版,得重新发。群里很快就出现了三个不同版本,有人用的还是旧版,算出来的数对不上,反过来问我"是不是算错了"。
问题三:换个电脑就没了。 有人换了工位、有人重装系统,文件就没了,又来找我要。
我意识到,这些问题的根源都一样:
我发的是"文件",但同事需要的是"服务"。
文件会丢、会旧、会找不到。而服务只有一个地址,永远是最新的那一个,谁都能打开,用不着安装任何东西。
说白了,我想要的效果是:
在公司任何一台电脑的浏览器里输入一个地址,回车,就能用。
而我们公司恰好有实现这个的东西——一台一直在跑的飞牛 NAS。

四、NAS 不只是个网盘
很多人对 NAS 的印象停留在"大号网盘"——存照片、存电影、备份手机。
但其实,你公司角落里那台一直开着的 NAS,本质上就是一台 7×24 小时不关机的 Linux 服务器。
网盘只是它的一个功能。它还能跑数据库、跑网站、跑内部系统。
我们那台飞牛上,已经在跑三个内部系统了——薪资的、设备参数的、发票的。同事每天都在用,只是没人意识到它们跑在 NAS 上。
所以思路很清晰:
把我这个 HTML 页面,变成 NAS 上的一个网站。
技术上叫"静态站点托管",说人话就是:在 NAS 上起一个 Web 服务,把我的 HTML 文件放进去,让局域网里的人都能访问。
工具用 Docker + nginx。nginx 是世界上最常用的 Web 服务器软件,Docker 则是"一键部署"的集装箱——我不需要在 NAS 上装 nginx、配环境,只要拉一个现成的"集装箱"下来,它里面已经把 nginx 装好了。
听起来很顺,对吧?
接下来我用了两个小时,才让它跑起来。
五、坑一:那个"明明是对的"地址
我翻开桌面的记事本,里面记着 NAS 的账号密码,还有一行:
地址:192.168.3.39我连上去,ping 不通。SSH 连不上。端口全超时。
我又查了一遍 SSH 是不是没开、防火墙是不是拦了。折腾了二十分钟。
最后我去问了行政,才知道——那个地址是半年前 NAS 换网段之前的旧地址。
现在的地址是 192.168.124.25。
改完,一次就连上了。
教训:动手之前,先花十秒钟验证目标是不是真的在那儿。
ping 192.168.124.25通了再往下做。不通,先解决网络,别去折腾 SSH 配置——那根本不是问题所在。
这件事给我的触动其实挺大:我们最容易犯的错,往往不是技术难题,而是"想当然"。
一份半年前的文档、一个记忆里的 IP、一句"应该没问题"。技术在变,记录不会自动更新。
六、坑二:文件在,但你打不开
连上之后一切顺利:建目录、传文件、拉镜像、起容器,一气呵成。
我打开浏览器,输入 http://192.168.124.25:5671——
403 Forbidden。
这就是那种最让人抓狂的错误。不是 404(找不到),是 403(拒绝访问)。
我第一反应是路径写错了。查了一遍,路径没问题。
第二反应是容器挂载错了。查了一遍,挂载也对。
我甚至进到容器里面,用 ls 看了一眼——
文件就在那儿。index.html,9,825 字节,安安静静地躺着。
文件在,路径对,但就是不让你看。
最后我去看 nginx 的错误日志,一行字解开了谜团:
open() "/usr/share/nginx/html/index.html" failed (13: Permission denied)权限被拒绝。我回头看了一眼文件的权限:
---------- 1 HMDadmin Users 9825 index.html前面那十个横杠,意思是:任何人都不能读、不能写、不能执行。
原因是我用 SFTP 传文件时,NAS 把这批文件创建成了"000 权限"——一个彻底上锁的柜子。
而容器里的 nginx 是以一个叫 nginx 的系统用户在跑,UID 是 101。它不是文件的主人,连看一眼的资格都没有。
一行命令解决:
chmod 644 /vol1/1000/muxiang-calc/html/*刷新页面,200,页面出来了。
这个坑为什么值得单独讲?
因为它的表象(403)和真相(权限)之间隔着一层。你很容易往"路径错了""配置错了"的方向去找,越找越远。
一个判断技巧:看到 403,先查权限,再查路径。
七、坑三:能打开,不等于算得对
页面出来了,我长舒一口气,觉得完事了。
但有个声音在我脑子里冒出来:我只是证明了"页面能打开",我证明过"它算得对"吗?
于是我做了一件当时看起来有点多余的事——
我造了一张测试表,故意塞进去七种不同的写法,包括一些"奇怪"的:
1350*800*600 | |
1200*1000*800mm | |
1.2*0.8*0.6m | |
1350×800×600 | |
L1350*W800*H600 | |
1350*800 |
结果出来,我后背有点发凉。
1350×800×600 这一行,成本算出来是 0。
不是报错,不是提示,是一个漂亮的、安静的 0。
原因:代码里只把英文的 x 当成了乘号,没处理中文输入法打出来的全角 ×。匹配失败之后,程序走了兜底逻辑——把 1350×800×600 这一整串丢给 parseFloat,结果只认出开头的 1350,宽和高双双变成 0。
面积 = 0,成本 = 0。
如果没人发现,这个 0 就会被当成"这批货不要钱",一路流进报价单。
另一个问题更隐蔽。测试里有一行品名叫"外墙板木箱",它被判成了国外,单价从 26.17 跳到 33.64。
原因:代码判断国内外用的是"品名里有没有'外'这个字"。
"外墙板"里有个"外"字。于是它被当成了出口生意。
溢价 28.5%,而且没有任何提示。
我盯着这两行看了很久,想到一件事:
一个静默算错的程序,比一个直接崩溃的程序危险得多。
崩溃了你会去修。算错了,你可能永远不知道。
后面的修复不复杂:补齐全角乘号、把"外"这个判断条件收窄到只认"国外"和"出口"、再加一列"备注"——凡是解析不出来的行,明确标出来,页面上还会汇总提示"有几行异常"。
修完再跑一遍,七行全对。
这才是完整的交付。
八、手把手教程:你也可以照着做一遍
好,故事讲完了。下面是可以直接照抄的操作手册。
我尽量写成"不需要懂 Linux 也能做"的版本。
0. 你需要准备什么
一台 NAS(飞牛、群晖、威联通都行,只要能跑 Docker) 一个做好的 HTML 工具(没有的话,可以让 AI 帮你写一个) 你的电脑和 NAS 在同一个网络里
关于 HTML 工具:这其实是整个方案里最灵活的一环。你可以是 Excel 处理工具、报价计算器、排班表生成器、合同模板填充器——任何"输入数据、输出文件"的重复劳动,都能做成这样一个页面。<br><br>关键是让它纯前端:所有计算都在浏览器里完成,不传服务器。这样既安全,部署也最简单。
1. 确认 NAS 地址(别跳过!)
这是我踩的第一个坑。
登录 NAS 的网页后台(飞牛一般是 http://你的IP:5666),在系统设置里看当前的 IP 地址。
然后在你电脑上验证:
Windows:按 Win+R,输入cmd,回车,输入ping 192.168.124.25(换成你的地址)看到"来自……的回复"就是通的 看到"请求超时",先解决网络问题,别往下做
2. 开启 SSH
SSH 就是远程命令行。飞牛在"系统设置 → 开发者选项/SSH"里开启,群晖在"控制面板 → 终端机和 SNMP"。
记下账号密码。
如果你完全不想碰命令行,可以跳过 SSH,直接用 NAS 自带的文件管理器上传文件 + Docker 面板启动容器,也能完成。教程后面会标注哪些步骤可以纯图形界面完成。
3. 规划端口(很重要)
先看一眼 NAS 上已经用了哪些端口:
docker ps我那台的情况是:
所以我用了 5671,顺着规律往下排。
两个提醒:
NAS 的 80 端口通常已经被系统自己占用了,不要映射 80 选端口前先 docker ps看一眼,别撞车
4. 上传文件
方法 A(推荐,纯图形界面):
打开 NAS 的文件管理器,在 /vol1/1000/ 下新建一个文件夹,比如 muxiang-calc,里面再建一个 html 文件夹,把你的 HTML 文件放进去。
方法 B:用 WinSCP / FileZilla 这类工具,协议选 SFTP,端口 22,填账号密码,拖上去。
目录结构最终长这样:
/vol1/1000/muxiang-calc/ └── html/ └── index.html5. 启动服务
方法 A(图形界面):
NAS 的 Docker 面板里,找到"项目 / Compose",新增,路径选 /vol1/1000/muxiang-calc,粘贴下面这段:
services: muxiang-calc: image: nginx:alpine container_name: muxiang-calc restart: unless-stopped ports: - "5671:80" volumes: - ./html:/usr/share/nginx/html:ro environment: - TZ=Asia/Shanghai方法 B(命令行):
docker run -d --name muxiang-calc --restart unless-stopped \ -p 5671:80 \ -v /vol1/1000/muxiang-calc/html:/usr/share/nginx/html:ro \ -e TZ=Asia/Shanghai \ nginx:alpine几个参数解释一下:
--restart unless-stopped:NAS 重启后自动恢复。这一条很重要,不然哪天断电重启,你的服务就没了 -p 5671:80:外面用 5671 端口,容器里面是 80 -v ...:/usr/share/nginx/html:ro: ro是只读,更安全nginx:alpine:轻量版 nginx,体积小、启动快
6. 修权限(最容易翻车的一步)
如果你是用图形界面上传的,这步可能不需要。如果是 SFTP 传的,一定要检查:
ls -la /vol1/1000/muxiang-calc/html/看到 -rw-r--r-- 才是正常的。如果看到 ----------,执行:
chmod 755 /vol1/1000/muxiang-calc /vol1/1000/muxiang-calc/html chmod 644 /vol1/1000/muxiang-calc/html/*7. 访问验证
浏览器打开 http://你的NAS地址:5671。
能打开只是第一步。 请务必再做一件事:
拿一份真实数据,跑一遍,人工核对至少三行。
这是我在坑三里学到的教训。页面能返回 200,和它算得对,是两件完全不同的事。
8. 避坑清单
pingdocker ps | ||
ls -lachmod 644 | ||
ls 看一眼 | ||
| 能打开但算错了 | 逻辑缺陷 | 必须拿真实数据核对 |
最后一行,是整篇文章最想说的一句。
九、写在最后
这件事从头到尾,大概花了我一个下午。
但有意思的是,真正写代码的时间不到十分钟——那部分 AI 帮我做了。剩下的时间,几乎全花在"让它能被别人方便地用到"上。
这大概是很多内部工具的真实处境:
做出来,只完成了 20%。让同事真的用起来,才是剩下那 80%。
那个下午之后,小杨不再需要对着屏幕一个一个数了。她只需要打开一个网址,把表拖进去,两秒后下载。
而我收获最大的,其实是那个"多此一举"的测试环节。
如果我当时看到页面返回 200 就收工,那个算出 0 的成本会一直躺在那里,直到某天在报价单上炸开。
"能打开"从来不等于"没问题"。
这句话不只适用于代码。
*如果你也想把部门的某个重复劳动做成这样一个工具,欢迎在评论区说说你的场景。*