在柬埔寨、老挝、缅甸开店:小票上的当地文字怎么才印得对
这三个国家的华人店铺不少,收银系统却是这份资料里最容易踩坑的一类。
先把结论放前面,方便你直接拿去问供应商:
- 高棉文(柬埔寨)、老挝文、缅甸文,热敏打印机的自带字库里基本没有, 也没有任何一套"编码"能补上。 别的文字还能靠换编码解决,这三种连编码都不存在。 唯一可行的做法是软件先排好版、渲染成图片再打印。
- 缅甸文还多一个坑:市面上流通着两套写法,用的是同一批字符编号。 商品资料导进系统时不报错、存进去也不报错,打出来却是另一串字。 不认识缅甸文的人,从头到尾看不出问题。
- "我们做过泰国,这几个国家差不多"——这句话只对了三分之一。 老挝文确实和泰文很像,柬埔寨文和缅甸文完全是另一套东西。
本文核对状态
文字本身的部分,是照 Unicode 标准字符数据库(
UCD 13.0.0) 一个字符一个字符核对过的:每个元音符号的属性、柬文叠字符号的属性、 各国数字的编号范围、有没有货币符号,字符数和字节数都是实际数出来的。 断行规则读的是 Unicode 官方文档UAX #14(第 55 版,2025-09-05)。 "没有编码"这一条,查的是微软官方公布的编码页清单。这部分比较硬。打印机怎么表现、当地小票习惯、税务规定,全部没核实。
待核实清单 ——
TODO: verify
- 你要买的那台打印机,字库里到底有没有这三种文字。大概率没有, 但要自己确认,别信参数表上写的"支持多国语言"。
- 打印机印图片的能力:最大宽度多少点、印一张全图片小票要多久。 接受了第一节的结论之后,这条就是最关键的一条。
- 店里真正要用的那台收银机上有没有对应字体和断词词库。 不是供应商演示用的电脑。这条是最常见的翻车点。
- 你手上现有的缅甸文商品资料,到底是哪一套写法,会不会两套混在一起。
- 当地小票上是印本地数字还是印阿拉伯数字(
0–9),是习惯还是规定。- 缅甸的货币在小票上怎么写 —— Unicode 里根本没有缅元的货币符号。
- 税务、发票、小票必印字段,这份资料一个字都没有。 柬埔寨、老挝、缅甸三个国家篇一篇都没写过,必须另外找当地会计。见第八节。
一、为什么"换个编码"这条路走不通
热敏打印机自带字库的工作方式是:一个字节对应一个图形。要用这条路, 前提是这门文字有一套现成的"编码表",把字符和字节对应起来。
泰文有。微软公布的编码页清单里,泰文有三条(windows-874、x-mac-thai、
还有一条 IBM 的),越南文有一条(windows-1258),印度那边九种文字有九条。
高棉文、老挝文、缅甸文,一条都没有。 不是少,是零。 Windows 没有、苹果没有、IBM 没有,国际标准 ISO/IEC 8859 里也没有相应的部分。
这件事对三种文字的意义不太一样,值得分开说:
柬埔寨文和缅甸文没有编码,是正常的。 这两种文字里,一个字母印成什么样 取决于它前后跟着什么,好几个字符会合并成一个图形, "一个字节对一个图形"这套机制根本表达不了。就算给它分配编码也没用。
老挝文没有编码,才是真正要注意的地方。 老挝文的结构和泰文非常接近 ——
一个辅音,上面下面挂符号,前置元音按看到的顺序存,不合并成新图形。
泰文能用 windows-874,老挝文本来完全可以有一套一样的编码。
但从来没人做过这套标准。
所以老挝这个市场的情况是:技术上最简单,可省事的路照样没有。 供应商说"泰国我们做过,老挝一样",前半句是真的,后半句会让你多花一笔钱。
对你的实际影响: 这三个国家的小票,必须是收银机先把字排好、 渲染成一张图片,再整张发给打印机。这个决定要在买打印机之前定下来, 因为要看的是打印机印图片的能力和速度,不是它的字库列表。 等到验收时才发现,打印机已经买了。
还有一个副作用值得记住:别的国家小票印出乱码,多半是编码选错了; 这三个国家不可能是编码选错,因为压根没有编码可选。 同样的症状在这里只可能是别的原因 —— 缺字体、收银机上没装排版引擎, 或者第二节说的那个。
二、缅甸文最大的坑:两套写法,同一批字符编号
缅甸有一套流通很广的旧写法,叫 Zawgyi。它用的是和标准写法完全相同的 那批字符编号,只是每个编号代表的意思不一样。
为什么这件事对开店的人是个实际问题:
存进系统不报错,导出来也不报错。 两套写法都是合法的 UTF-8,
数据库不会拒绝,Excel 不会提示,导入工具不会报警。
存进去是什么,取出来还是什么,一个字节都不差 —— 只是印出来是另一串字。
数据里没有任何地方写着"这是哪一套"。 编码标注两边都是 UTF-8,
数据库字段类型也一样。区别只存在于看的人装的是哪套字体,
而字体不在数据里。
自动识别只能算概率,不能算确定。 谷歌开源的 Zawgyi 识别工具
(myanmar-tools)用的是训练出来的模型,不是写死的规则,
项目自己给的理由是:写死规则的识别器会把掸语、孟语的正常文字误判成 Zawgyi。
掸语孟语用的字符编号确实和 Zawgyi 占用的那批重叠(这一点照 UCD 核对过)。
如果你店里有掸族员工、卖掸语标注的商品,这正是最容易被误伤的情况。
转换规则是有标准出处的。 Zawgyi 和标准写法之间的转换规则收在 CLDR 里,
CLDR 是 Unicode 官方的数据库。myanmar-tools 这个工具本身,项目页面上
明确写着不是谷歌的官方产品 —— 两者的可信程度不一样,别混为一谈。
两个方向都是"看起来正常"。 旧写法的数据用新字体看, 或者新写法的数据用旧字体看,出来的都还是一段像模像样的缅甸文, 不是方框也不是问号,只是字不对。不认识缅甸文的人看不出任何异常。
它一般不是从软件进来的,是从商品资料进来的: 供应商发的表格、 店员用自己手机打的商品名、上一套系统里导出来的菜单。
该怎么办: 在导入商品资料的时候就处理掉 —— 识别、转换、 记下这批资料原来是哪一套。不要留到打印的时候再处理, 因为那时候同一个字段里两套都有,没有统一的答案。
三、老挝像泰国,柬埔寨和缅甸不像
这三种文字都有一类"前置元音"—— 读音在辅音后面,写出来却在辅音左边。 泰文也有。但存的方式不一样,这决定了很多事情。
照 Unicode 字符数据库核对,区别一眼能看出来:
| 文字 | 前置元音编号 | 字符类别 | 数据里怎么存 | 打印时要不要调顺序 |
|---|---|---|---|---|
| 泰文 | U+0E40–U+0E44 |
Lo |
按看到的顺序,存在辅音前面 | 不用 |
| 老挝文 | U+0EC0–U+0EC4 |
Lo |
按看到的顺序,存在辅音前面 | 不用 |
| 高棉文 | U+17C1–U+17C3 |
Mc |
存在辅音后面 | 要 |
| 缅甸文 | U+1031 |
Mc |
存在辅音后面 | 要 |
Lo 是"字母",能独立存在;Mc 是"要挂在别的字上的符号",单独没有意义。
老挝文和泰文,存的顺序就是印的顺序。 排版时不需要调换。
柬埔寨文和缅甸文,存的顺序和印的顺序是两个顺序。
和印度那一类文字一样。实测:缅甸文 U+1000 U+1031 是两个字符、六个字节,
印出来第二个字符在第一个的左边。
这件事在店里表现成四个具体问题:
- 商品名太长要截断时,柬文缅文可能把辅音截掉、把符号留下。 留下的符号会挂到后面的字上,或者印出一个空心圆圈。 正确做法是"按用户看到的一个字"截,不是按字符数截。
- 在收银机上输商品名时,按退格键删掉的可能不是屏幕上最右边那个东西。
- 商品列表按字母排序,四种文字都会排乱,但原因不同: 泰文老挝文是前置元音排到了前面,柬文缅文是符号顺序的问题。 这条小票上完全看不出来,但店员每天找商品都要多花时间。
- "我们做过泰国"这句话,对老挝成立,对柬埔寨和缅甸不成立; "我们做过印度"这句话,对柬埔寨和缅甸的排版成立,对缅甸的编码问题不成立。
四、柬埔寨文是往下叠的
高棉文有一种叠字:第二个辅音叠在第一个下面。
负责叠的那个字符是 U+17D2,它本身不印出任何东西,
只是一条"把下一个字叠到下面去"的指令。
实测几个例子:
| 一个字里有 | 字符数 | 字节数 | 印出来 |
|---|---|---|---|
U+179F U+17D2 U+178F |
3 | 9 | 一个字母,下面叠一个 |
U+179F U+17D2 U+178F U+17D2 U+179A |
5 | 15 | 一个字母,下面叠两个 |
U+1781 U+17D2 U+1789 U+17BB U+17C6 |
5 | 15 | 一整摞,只占一格宽 |
对你意味着三件事:
五个字符只占一格宽。 系统如果按字符个数去算对齐, 柬文商品名那一列一定会歪 —— 而且用英文测试数据测的时候一切正常。
行距不够会把下面叠的部分切掉。 泰文是上面的声调符号容易被切, 柬文是下面叠的辅音容易被切。切掉之后不是缺一块,是变成另一个词。
千万别让系统"清理"商品名里的不可见字符。 U+17D2 看起来像垃圾字符,
其实是关键指令;柬文还会用 U+200B(零宽空格)标词的边界,
清掉之后断行位置也跟着乱。这两个字符在屏幕上都看不见,
肉眼检查商品资料是查不出来的。
柬文还有一种元音(U+17C4、U+17C5),印出来一半在字母左边、
一半在右边。这类元音在数据里是一个字符,没有办法拆开处理。
五、数字和货币符号
三种文字各有自己的一套数字,缅甸文那套还有两份:
| 文字 | 数字 | 编号范围 |
|---|---|---|
| 高棉文 | ០១២៣៤៥៦៧៨៩ | U+17E0–U+17E9 |
| 老挝文 | ໐໑໒໓໔໕໖໗໘໙ | U+0ED0–U+0ED9 |
| 缅甸文 | ၀၁၂၃၄၅၆၇၈၉ | U+1040–U+1049 |
| 掸文 | ႐႑႒႓႔႕႖႗႘႙ | U+1090–U+1099 |
小票上到底印本地数字还是印 0–9,是当地习惯问题,
这份资料没核实过(TODO: verify)。但有两条不管在哪都成立:
这件事要做成模板里的一个开关,不能写死在程序里;
同一张小票上绝对不能两种数字混着印。
缅甸有一对特别容易混的字符: U+1040(缅甸数字零)和
U+101D(缅甸字母 wa)是两个不同的字符(这一点核对过),
但长得很像,打字时经常拿字母当零用。
后果是:数量、电话号码这类字段里存进去一个字母,
系统搜不到、对不上、算不了 —— 而且看上去完全正常。
货币符号:柬埔寨和老挝有,缅甸没有。
把 Unicode 里所有货币符号翻了一遍:柬埔寨瑞尔有(U+17DB,៛),
老挝基普有(U+20AD,₭),缅元一个都没有。
所以缅甸的价格该怎么印 —— 用拉丁字母缩写、用缅文写、还是用国际货币代码 ——
这是当地习惯,本文没核实,你要自己确认后再定模板。
另外,柬埔寨在零售场合常被描述成美元和瑞尔一起流通。 如果属实,对收银的影响很直接:一个柜台两种货币、 标价一种货币找零另一种、汇率要有人维护。 但这属于国家篇的内容,而本资料没有柬埔寨国家篇, 所以这里只把它列成待核实项,不给答案。
六、断行:这三种文字词和词之间不空格
和泰文一样,这三种文字写起来是连续的,词和词之间不留空格。
Unicode 官方文档 UAX #14 把泰文、老挝文、高棉文、缅甸文归成同一类
(SA),意思是:光看字符本身判断不出哪里可以断行,必须查词库。
没有词库会怎样:系统只能在排不下的地方硬断, 结果是每一个长商品名都从中间断开。 中文断在哪里都还读得懂,这几种文字断错了就是另一串字。
好消息是标准库里有现成的词库。ICU 的官方文档明确写着, 中文、日文、泰文、老挝文、高棉文、缅甸文都有词库支持,而且是自动生效的。 这三种文字全在名单上。
两件事要提醒:
渲染成图片解决不了断行。 断行发生在渲染之前。 先断错了再渲染,只是把错的结果印得很清楚。
要确认词库在店里那台收银机上。 词库是随程序打包的数据, 便宜的安卓收银机为了省空间经常裁掉。开发用的电脑上有,不代表收银机上有。
七、验收清单
每一条都要找一个真正认识这门语言的人来看,不是"认得这是柬埔寨字"就行。
| # | 测什么 | 什么算通过 |
|---|---|---|
| 1 | 印一个带两层叠字的柬文词 | 两个都叠在下面,底下没被切掉 |
| 2 | 印一个带前置元音的缅文词(U+1031) |
元音印在辅音左边 |
| 3 | 印一个带 U+17C4 的柬文词 |
元音一半在左一半在右 |
| 4 | 印一个多层符号的缅文字 | 是一个整体,没有空心圆圈 |
| 5 | 把商品名截断后打印 | 整个字一起消失,不留半截符号 |
| 6 | 印一个长到要换行的商品名 | 断在词和词之间,不是从词中间断开 |
| 7 | 印三行长短不一的商品 | 金额小数点对齐 |
| 8 | 印一整行满纸宽的当地文字 | 印到纸边,右边没被切掉 |
| 9 | 印一个带 ៛ 或 ₭ 的价格 | 符号印得出来,不是方框 |
| 10 | 印一个缅甸的价格 | 和第五节确认的当地写法一致 |
| 11 | 导入一批已知是旧写法的缅甸文商品资料 | 被识别并转换,或者被拒绝,不能不声不响存进去 |
| 12 | 在数量字段里输入 U+101D |
被当成非数字拒绝,不能存成零 |
| 13 | 商品列表按当地文字排序 | 顺序和当地人预期一致 |
| 14 | 印一个掸语商品名 | 没有被误判成旧写法然后"改正" |
| 15 | 把一笔已完成的交易重新打印一次 | 和原来那张完全一样 |
| 16 | 以上全部在店里那台真机上再做一遍 | 和演示时结果一致 |
第 2、5、11、12、14 条,出问题的时候看起来都是正常的。 第 14 条之所以要单独测,是因为"修复旧写法"这个功能本身也会把好数据改坏。
第 16 条最容易被跳过。演示用的笔记本电脑和店里的收银机不是一台机器。
八、这份资料没覆盖的部分
柬埔寨、老挝、缅甸,这三个国家的国家篇一篇都没写。
也就是说:税率多少、价格要不要含税展示、小票上必须印哪些字段、 税号什么格式、收银机要不要向哪个部门登记、现金抹零合不合法、 柬埔寨双币怎么处理 —— 本资料一条都没查过,一条都不敢写。
这些必须找当地会计或者报税代理确认。系统供应商不是这方面的责任人, 也别指望他们替你把关。
九、双语怎么配
这三个市场的华人店铺,常见的配法是:后台管理用中文, 小票和顾客看到的部分用当地文字。 员工是本地人,老板看中文报表。
这个配法本身没问题,但有一件事要提前问清楚: 后台和小票是不是两套独立的语言设置。 有些系统只有一个"语言"开关,一改全改, 结果是老板把界面切成中文之后,小票也跟着变成中文了。
另外,屏幕上缺字体和小票上缺字体,暴露的速度完全不一样: 屏幕上显示成方框,员工当天就会来说; 小票上印错了,是顾客拿走扔掉,你可能几个月都不知道。 所以验收一定要以打印出来的小票为准,不能只看屏幕。
十、挑系统时该问清楚的问题
可以直接拿去问供应商:
- 你们印高棉文/缅甸文小票,是靠打印机字库,还是软件渲染成图片? —— 回答"靠字库"或者"加个编码就行"的,基本可以判断没做过。
- 能不能现在就打一张当地文字的样票给我看? —— 要求当场打,不接受截图。
- 能不能用你们实际会卖给我的那台收银机和打印机打? —— 不是用笔记本电脑打。这条最关键。
- 你们怎么处理缅甸文的两套写法?导入商品资料时会不会识别? —— 反问"什么两套写法"的,说明没做过缅甸。
- 商品名太长要截断时,你们按什么单位截? —— 应该回答"按用户看到的一个字",回答"按字符"或"按字节"的有问题。
- 导入商品资料时你们会不会清理不可见字符? —— 会的话,要确认不会把柬文的叠字符号和零宽空格一起清掉。
- 收银机上装了哪些字体?有没有断词词库?能不能列出来? —— 要具体名字,不接受"支持多国语言"这种回答。
- 后台语言和小票语言是不是分开设置的?
- 打印机印图片的最大宽度是多少?印一张全图片的小票要多久?
- 你们在柬埔寨/老挝/缅甸做过几家店?能不能给我看一张真实的小票?
- 税务这块,你们做过当地的实施吗? —— 这份资料完全没覆盖税务,无论对方怎么回答, 你都要另外找当地会计确认一遍。
由秘奥软件(MISAll)团队维护。最后更新:2026-08