为什么所有金额数值都是负数?
Why are all the amounts values negative?

原始链接: https://bankstatementconverter.com/blog/posts/2026-08-02-why-are-all-amounts-negative/

有客户反馈称,他们转换后的 PDF 对账单显示所有金额均为负数。经调查发现,该 PDF 使用了尾随负号格式。对于正值,文档中也包含了一个负号,但将其颜色设置为与背景相同,从而使其对肉眼不可见,却能被提取软件检测到。 PDF 创建者很可能使用这种“不可见”字符,是为了在不计算负号宽度的情况下,保持正数右对齐的间距一致性。 为解决此问题,我考虑了两种方案: 1. **OCR**:将页面转换为图片并通过 OCR 处理。虽然有效,但速度较慢且容易出现字符识别错误。 2. **颜色过滤**:识别并忽略非黑色的文本元素。由于我目前的转换器不跟踪文本颜色,因此需要更新代码以捕获颜色属性。 我计划采用颜色过滤方案,因为它比 OCR 更准确、高效。

对不起。
相关文章

原文

A few days ago I got this email from a customer. Something about all the amounts coming out as negative. I converted their PDF.

PDF Sample

Converted Sample

The customer was right, all amounts were coming through as negative. Pretty weird. Interestingly the column headers end with minus sign characters. I then opened up the PDF in PDFSnake to see how the text is encoded. Let’s look at how the values “$110.00-” and “$1,527.57” are encoded.

$110.00-

PDFs are made up of a series of commands. Let’s walk through the commands that appear in this segment.

BT: Begin Text. Tells the PDF renderer to enter into text rendering mode and to save the previous graphics state. Only text operators are legal when inside a Begin Text and End Text block.

ET: End Text. Tells the PDF to exit text rendering mode and restore the graphics state to what it was before the BT command.

Tf: Set text font and size.

Td: Move text position.

Tj: Show text.

g: Set grey level for non-stroking operations.

G: Set grey level for stroking operations.

The above PDF commands could be summarise as “Draw the text ($110.00). Set the grey level to 0. Draw the text (-)”

$1,527.57-

We’ve seen all these commands before and the structure is similar. However there is one key difference. The gray level is set to 0.878 when drawing the minus sign character. The gray level of the minus sign is the same gray level as the background colour. This makes the minus sign invisible. The character is there, but it is not visible and that’s why it comes through when my code processes this PDF.

Why did they encode this PDF like that?

I don’t know, but I can have a guess.

They used trailing minus signs in this PDF. Trailing minus signs make right alignment a bit difficult, because they didn’t just want basic right alignment, they wanted right alignment for the number elements ignoring the minus sign. One way you can achieve this is by always leaving space for the minus sign. But how wide is the minus sign? It depends on the font size, maybe it’s hard to predict. So instead they put in an invisible minus sign for postive values.

Great the PDF looks good, but extracting data from it is a pain. They could avoid all this if they used leading minus signs, but for some reason they wanted trailing minus signs. Okay so now we know why this problem is occuring, how can we get this PDF to convert properly. I can see two solutions.

Solution #1 - OCR the PDF

Instead of reading the text elements in the PDF I could convert the PDF into a series of PNG files and then run OCR software on the PNG files. This should work although it has some downsides. OCRing isn’t 100% accurate. It works pretty well but there’s always a chance that characters are incorrectly recognised. OCRing is significantly slower.

Solution #2 - Strip out non-black text

For this statement type only black coloured text is relevant. Text elements that are set to any other colour can be treated as invisible. This should work, however there’s one problem. When extracting text in Bank Statement Converter, I do not store the colour of the text. So I’ll need to add in code to do this. It shouldn’t be too hard though.

联系我们 contact @ memedata.com