当使用绝对定位(在我猜的范围内?)将对象放置到 pdf 页面上时PdfContentByte
,它位于从左下角开始的坐标系内。
我想以系统从左上角开始的方式翻转坐标。在向页面添加任何内容之前,我会先进行翻转。
我试过用这个
cb.concatCTM(1f, 0f, 0f, -1f, 0f, PageSize.A4.getHeight());
但是后来添加的对象被翻转了(我不希望发生这种情况)。
您对 PDF 坐标系应用的任何变换不仅会改变您提供页面上某个点坐标的方式;相反,它还会更改PDF 查看器绘制其对象的坐标系。例如
(第 8.3.3 节ISO 32000-1中的常见转换)
如果您以系统从左上角开始的方式翻转坐标,那么您也翻转了绘制的对象。在文本对象的情况下,您可以通过原位翻转的文本矩阵在本地撤消翻转。
不过,这意味着相当麻烦。如果将原点放在页面上的左上角和负 y 坐标就足够了,我建议您只翻译坐标系。
如果您需要坐标系的原点位于左上角,则习惯使用简单的数学来更改坐标。为此目的使用不同的 CTM 会更加复杂,并且可能会导致各种副作用,正如您自己所经历的那样。例如:旋转 CTM 也会旋转内容(文本可以上下颠倒、镜像,...)。
为什么不简单地使用重新计算坐标的方法。例如:您希望从页面顶部开始计算坐标 (10, 10),然后使用 transform(pagesize, y) ,其中 transform 方法的定义如下:
public float transform(Rectangle pagesize, float y) {
return pagesize.top() - y;
}
这样,您可以执行以下操作:
float x = 50;
float y = transform(pagesize, 50);
table.writeSelectedRows(0, 10, x, y, canvas);
就个人而言,我认为不尊重 ISO-32000-1 中定义的坐标系是一个坏主意,因为您更喜欢使用一个奇怪的坐标系,其中增加 Y 值指向向下而不是向上(这太违反直觉了),但是如果你坚持这样做,除非你的 PDF 文件真的很大,否则你不应该篡改 CTM。
首先:原谅我的英语。我是西班牙人xD
这是我的解决方案:
我一直在寻找同样的东西。我想在左上角有原点。
好吧,你不能改变它,但你可以做另一件事。
如果你想要每页的高度,你必须从 PdfReader 类中获取页面的裁剪框。
因此,例如,如果你想获得垂直位置“y = 60”,考虑到左上角的原点,你必须这样做:
PdfReader reader = new PdfReader("yourFile.pdf");
Float y = reader.getCropBox(pageNumber).getHeight()-60;
如果您有一个具有不同页面高度的 pdf 文档,这非常有用。
该解决方案在我的应用程序中帮助了我:
PdfReader reader = new PdfReader("yourFile.pdf");
Float y = reader.GetPageSize(pageIndex).Height-60;
Float y = reader.GetPageSize(pageIndex).Height-60-rectangleHeight;
也许您也必须计算添加/操作对象的尺寸。我在我的应用程序中添加矩形。