14

我正在使用PDFKit.org通过 JavaScript 生成 PDF。

该文档非常不言自明,但我面临一个未解决的问题,我猜一些 StackOverflow 成员可能已经找到了一个技巧来做到这一点。

我必须在某个时候旋转文本,并且文档仅说明如何旋转形状(如 a rect())。

我已经尝试了几件事,但到目前为止都没有。

所以我正在寻找一种通过调整代码来旋转它的方法,或者你们中的一些人可以向我展示我可能错过的文档的一部分?

4

4 回答 4

25

没有什么特别的技巧,但正确理解如何在 PDFKit 中应用转换至关重要。

要了解的主要内容是您不旋转文本或形状:您旋转文档,如doc.rotate(...).rect(...).

它可能会帮助您将文档视为具有物理属性的画布。它的特性之一是它的旋转。
如果您想在一页纸上绘制旋转的文本,您可能会做的是物理旋转页面,然后像往常一样水平写入一些文本,然后将页面旋转回正常状态。
你最终得到的是一个在直页上的旋转文本:

这正是 PDFKit 的工作方式:您在文档上应用转换,在转换后的上下文中绘制您需要绘制的所有内容,然后将文档恢复到之前的状态。

要实现这一点,您有两种方法:doc.save()doc.restore().

  • save() 在应用转换之前使用,这样之前绘制的所有内容都不会受到影响。
  • 然后你可以变换你的画布并绘制你需要的东西
  • 绘制完需要转换的所有内容后,调用restore()以将文档恢复为初始状态。它基本上会回滚在最近一次save()调用之后执行的所有转换(即旋转、缩放、平移)。

要(有点)重现上面的图表,你会这样做:

doc.text('text', ...)
doc.save()
doc.rotate(90).text('rotated text', ...)
doc.restore()

最后要理解的一件事是您的文档的坐标系会受到转换的影响:

因此,如果text在坐标处绘制(0, 0),则rotated text在类似的位置绘制(0, documentHeight / 2 - offset)
使用 90 度旋转的倍数时很容易处理,但否则你将不得不使用三角函数 :)

为方便起见,您可以使用旋转的原点来确保您围绕一个对您的下一张图纸有意义的点旋转文档!

于 2017-01-05T10:59:59.843 回答
8

编写旋转文本的最佳方法是围绕某个点(您希望文本的起点)旋转 pdf,然后编写它并将 pdf 文档旋转回来。代码示例:

doc.rotate(angle, { origin: [x,y] });
doc.text( 'TEST', x, y);
doc.rotate(angle * (-1), { origin: [x,y] });

这样你就不需要计算一个新的位置。

同样值得知道的是 pdfkit 将我们文本的 x 和 y 作为我们文本“框”的左上点(在我的情况下确实很重要)。

于 2017-08-08T11:51:38.797 回答
1

对于答案中描述的问题或事实,我把头发拉了一点。尝试了很多东西,但文本最终总是走自己的路。

这是我用来将文本放置在不同方向的小剪辑。该函数在旋转坐标系中计算新的 x 和 y。

var doTransform = function (x, y, angle) {
var rads = angle / 180 * Math.PI;
var newX = x * Math.cos(rads) + y * Math.sin(rads);
var newY = y * Math.cos(rads) - x * Math.sin(rads);

return {
    x: newX,
    y: newY,
    rads: rads,
    angle: angle
    };
};

然后,这个会遍历具有 x,y,rotation 的文本数组。Uncerscore 用于循环。

var drawTexts = function (doc, texts) {

_.each(texts, t => {
    doc.save();
    doc.fontSize(t.size);
    var loc = doTransform(t.x, t.y, t.rotation);        
    doc.rotate(t.rotation);        
    doc.text(t.text, loc.x, loc.y);               
    doc.restore();
    });

};

首先旋转“世界”,然后将文本放置到与 (tx,ty) 相同但在旋转世界中的新 (x,y) 位置。

于 2017-08-01T17:06:40.640 回答
-1

您可以使用 svg。见https://pdfmake.github.io/docs/document-definition-object/svgs/

pdfmake 为此使用 svg-to-pdfkit。

源代码似乎支持 transform="rotate...." ,请参阅https://github.com/alafr/SVG-to-PDFKit/blob/master/source.js#L431

    } else if (func === 'rotate' && nums.length === 3) {
      let a = nums[0] * Math.PI / 180;
      result = multiplyMatrix(result, [1, 0, 0, 1, nums[1], nums[2]], [Math.cos(a), Math.sin(a), -Math.sin(a), Math.cos(a), 0, 0], [1, 0, 0, 1, -nums[1], -nums[2]]);
    }
于 2020-06-09T19:25:52.133 回答