夜雨聆风学习资料网

ARTICLE · 1032662

一个 Excel 表格折磨了整个部门,我用一个网址终结了它

一个 Excel 表格折磨了整个部门,我用一个网址终结了它

——把网页搬进公司 NAS 的全过程,以及我踩过的 4 个坑


一、那个让人眼花的下午

上周五下午四点,我路过财务部,看见小杨正对着屏幕一个一个数。

屏幕上是一张采购清单,几百行。每一行都有一列"货品规格",里面是些这样的内容:

1350*800*600 1200*1000*800mm 1.2*0.8*0.6m L1350*W800*H600

她要做的事,是把这些数字拆成长、宽、高,算出木箱的表面积,再乘以单价和数量,得出成本金额。

"这个你手算?"我问。

"不然呢,"她头也没抬,"规格写法还不一样,有的是毫米,有的是米,有的还带字母 LWH,有的还写个'出口'。我得一个个看清楚。"

我站在那儿看了三分钟。三分钟,她算了四行。

按这个速度,几百行得算到明天。但比慢更麻烦的是另一件事——

算错了,没人知道。

一个 1350 看成 13500,一个"出口"漏看了,成本就差出去一截。而这几百行数字,最后是要拿去报价的。

我说:"你把这个表发我一份,我试试。"


二、两百行代码,能顶三个人

我把表格拿回工位,没有马上写代码。我先想了一个问题:

这件事的本质是什么?

不是"算平方"——平方公式谁都会。真正的麻烦在三件事:

  1. 格式不统一
    :毫米、米、带单位、带字母前缀,人眼能分辨,公式不行。
  2. 规则要判断
    :品名里带"出口"的走国外价,不带的走国内价。
  3. 结果要写回原表
    :算完还得贴回去,不能只给个数字。

想清楚这三点,我就知道该找谁了——这种"规则明确、重复劳动"的活,正是 AI 最擅长的。

我把表头截图发给 AI 助手,描述了一遍需求,十分钟后拿到了一个 HTML 文件。

打开它,界面朴素得有点简陋:一个虚线框,写着"点击选择文件或拖拽到这里"。

我把那张表拖进去。

两秒后,浏览器自动下载了一个新文件。打开一看,原表最右边多出七列:

分类
平方
单价
成本金额
国内
1.35
0.8
0.6
4.74
26.17
248.09
国外
1.2
1
0.8
5.92
33.64
199.15

几百行,两秒。

而且这里有个关键设计:数据不出本机

这个页面没有后端,不联网上传,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

我那台的情况是:

端口
用途
5666
NAS 网页后台
5668
发票系统
5669
设备参数系统
5670
薪资系统

所以我用了 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.html

5. 启动服务

方法 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. 避坑清单

现象
真实原因
怎么查
完全打不开
IP/网段不对,或容器没起来
ping
 + docker ps
403 Forbidden
文件权限是 000
ls -la
 看权限,chmod 644
404 Not Found
文件名不是 index.html,或挂载路径错
进容器 ls 看一眼
端口起不来
端口被占用
换一个端口
能打开但点了没反应
依赖的 JS 库没传上去
打开浏览器 F12 控制台看报错
能打开但算错了逻辑缺陷必须拿真实数据核对

最后一行,是整篇文章最想说的一句。


九、写在最后

这件事从头到尾,大概花了我一个下午。

但有意思的是,真正写代码的时间不到十分钟——那部分 AI 帮我做了。剩下的时间,几乎全花在"让它能被别人方便地用到"上。

这大概是很多内部工具的真实处境:

做出来,只完成了 20%。让同事真的用起来,才是剩下那 80%。

那个下午之后,小杨不再需要对着屏幕一个一个数了。她只需要打开一个网址,把表拖进去,两秒后下载。

而我收获最大的,其实是那个"多此一举"的测试环节。

如果我当时看到页面返回 200 就收工,那个算出 0 的成本会一直躺在那里,直到某天在报价单上炸开。

"能打开"从来不等于"没问题"。

这句话不只适用于代码。


*如果你也想把部门的某个重复劳动做成这样一个工具,欢迎在评论区说说你的场景。*

相关学习资料