首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >PDFKit在使用for循环时将文本分割成两个相等的列

PDFKit在使用for循环时将文本分割成两个相等的列
EN

Stack Overflow用户
提问于 2022-06-03 19:06:21
回答 1查看 668关注 0票数 0

我试着用PDFKit来生成一个简单的pdf,在很大程度上,pdf是有用的,但是我有一个甲板构建API,它接收了很多卡片,每个对象我都想导出到一个pdf中,它和显示它们的名字一样简单,但是实际上,pdf一次只呈现一张卡片,并且只在一行上,我想要做的是让它把文本分割成列,这样itd看起来就像这样。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
column 1 | column 2
c1         c8
c2         c9
c3         c10
c4         c(n)

到目前为止,这是我的代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = asyncHandler(async (req, res, next) => {
  try {
    // find the deck
    const deck = await Deck.findById(req.params.deckId);

    // need to sort cards by name
    await deck.cards.sort((a, b) => {
      if (a.name < b.name) {
        return -1;
      } else if (a.name > b.name) {
        return 1;
      } else {
        return 0;
      }
    });
    // Create a new PDF document
    const doc = new PDFDocument();

    // Pipe its output somewhere, like to a file or HTTP response
    doc.pipe(
      fs.createWriteStream(
        `${__dirname}/../../public/pdf/${deck.deck_name}.pdf`
      )
    );

    // Embed a font, set the font size, and render some text
    doc.fontSize(25).text(`${deck.deck_name} Deck List`, {
      align: "center",
      underline: true,
      underlineColor: "#000000",
      underlineThickness: 2,
    });
    // We need to create two columns for the cards
    // The first column will be the card name
    // The second column will continue the cards listed
    const section = doc.struct("P");
    doc.addStructure(section);
    for (const card of deck.cards) {
      doc.text(`${card.name}`, {
        color: "#000000",
        fontSize: 10,
        columns: 2,
        columnGap: 10,
        continued: true,
      });
    }
    section.end();

    // finalize the PDF and end the response
    doc.end();
    res.status(200).json({ message: "PDF generated successfully" });
  } catch (error) {
    console.error(error);
    res.status(500).json({
      success: false,
      message: `Server Error - ${error.message}`,
    });
  }
});

目前,这确实生成了一个我想要的列顺序,但是这个解决方案有一个极端的警告,那就是,如果卡片文本不是很长,那么下一张卡片就会从同一行开始,如果我能找到一种方法让文本占据这一行的全部宽度,那将是有用的,但是我没有看到与之相关的任何事情。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-04 11:44:45

我认为问题在于,您依赖于PDFKit的文本" flow“API/逻辑,而当两张卡片不够大,无法在列上流动,并且在一列中得到两张卡片时,您就会遇到问题。

我想说的是,您真正想要的是基于初始文本示例创建一个表。

PDFKit还没有一个表API (还没有),所以您必须自己弥补。

这里有一种方法,您可以了解事物的维度:

  • 页面大小
  • 文本单元格的大小(手动为您自己选择,或者使用PDFKit来告诉您某个文本的大小)。

然后,使用这些大小来计算文本中可以容纳多少行和列。

最后,您将遍历over列,然后为每一页遍历行,将文本写入这些逐行的“坐标”(我通过“偏移”跟踪这些坐标,并使用它来计算最终的“位置”)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const PDFDocument = require('pdfkit');
const fs = require('fs');

// Create mock-up Cards for OP
const cards = [];
for (let i = 0; i <  100; i++) {
    cards.push(`Card ${i + 1}`);
}

// Set a sensible starting point for each page
const originX = 50;
const originY = 50;

const doc = new PDFDocument({ size: 'LETTER' });

// Define row height and column widths, based on font size; either manually,
//  or use commented-out heightOf and widthOf methods to dynamically pick sizes
doc.fontSize(24);
const rowH = 50;  // doc.heightOfString(cards[cards.length - 1]);
const colW = 150; // doc.widthOfString(cards[cards.length - 1]);  // because the last card is the "longest" piece of text

// Margins aren't really discussed in the documentation; I can ignore the top and left margin by
// placing the text at (0,0), but I cannot write below the bottom margin

const pageH = doc.page.height;
const rowsPerPage = parseInt((pageH - originY - doc.page.margins.bottom) / rowH);
const colsPerPage = 2;

var cardIdx = 0;
while (cardIdx < cards.length) {
    var colOffset = 0;
    while (colOffset < colsPerPage) {
        const posX = originX + (colOffset * colW);
        var rowOffset = 0;
        while (rowOffset < rowsPerPage) {
            const posY = originY + (rowOffset * rowH);

            doc.text(cards[cardIdx], posX, posY);
            cardIdx += 1;

            rowOffset += 1;
        }
        colOffset += 1;
    }

    // This is hacky, but PDFKit adds a page by default so the loop doesn't 100% control when a page is added;
    // this prevents an empty trailing page from being added
    if (cardIdx < cards.length) {
        doc.addPage();
    }
}

// Finalize PDF file
doc.pipe(fs.createWriteStream('output.pdf'));
doc.end();

当我运行它时,我得到了一个PDF,它有4页,如下所示:

改变colW = 250colsPerPage = 3

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72496768

复制
相关文章
python自动下载并更新chromedriver驱动
python用senium调用chrome时,需要使用chromedriver驱动,这个驱动需要对应chrome的版本。 而chrome又经常在后台偷偷升级,如果没关掉升级,之前的驱动又用不了。 其实用webdriver-manager听说也可以,但是他要到国外下载驱动,没办法使用。 这点很愁人,所以我这边开发了一个python自动下载并更新chromedriver驱动的程序。
星痕
2022/03/04
2.4K0
Chromedriver(谷歌浏览器驱动)安装教程「建议收藏」
这个报错一般都是第一次学习使用selenium自动化框架的时候出现的,主要的原因是因为selenium模拟的客户端对浏览器的操作,但没有找到相应浏览器的驱动导致的
全栈程序员站长
2022/08/18
6.7K0
Chromedriver(谷歌浏览器驱动)安装教程「建议收藏」
Python爬虫常用:谷歌浏览器驱动——Chromedriver 插件安装教程
我们在做爬虫的时候经常要使用谷歌浏览器驱动,今天分享下这个Chromedriver 插件的安装方法。
全栈程序员站长
2022/08/26
2.1K0
Python爬虫常用:谷歌浏览器驱动——Chromedriver 插件安装教程
安装Selenum的Chromedriver
http://chromedriver.storage.googleapis.com/index.html
老高的技术博客
2022/12/27
3250
安装Selenum的Chromedriver
Python 和 Selenium 的浏览器爬虫
Selenium 是一款强大的基于浏览器的开源自动化测试工具,最初由 Jason Huggins 于 2004 年在 ThoughtWorks 发起,它提供了一套简单易用的 API,模拟浏览器的各种操作,方便各种 Web 应用的自动化测试。
HoneyMoose
2023/09/20
3980
Python 和 Selenium 的浏览器爬虫
铬镍不锈钢的切削加工
  1Cr18Ni9Ti不锈钢的强度硬度很低(硬度≤187HB),而塑性很高,具有良好的耐酸性、耐腐蚀性。经固溶处理后的机械性能,屈服强度s0.2≥205MPa,抗拉强度sb≥520MPa,伸长率d5≥40%,收缩率y≥50%,用常规牌号的硬质合金刀具和常规方法加工很困难,原因是该材料的塑性及韧性较大,容易产生粘刀现象,断屑困难,同时产生振动,使刀具容易崩刃、磨损。
lrglu
2022/03/30
6640
铬镍不锈钢的切削加工
分享一个chromedriver谷歌浏览器驱动全部下载网址
https://npm.taobao.org/mirrors/chromedriver/
我去热饭
2022/05/18
1.1K0
java selenium chromedriver浏览器驱动放在哪里?【两种位置】
这个位置可以自己指定 比如将驱动放在项目根路径 D:\a-project\mqtest\ 需要在代码中指明driver的路径(绝对路径或相对路径),代码如下
小黑同学
2020/08/16
3.9K0
java selenium浏览器驱动 chromedriver放在哪里?【两种位置】
这个位置可以自己指定 比如将驱动放在项目根路径 D:\a-project\mqtest\ 需要在代码中指明driver的路径(绝对路径或相对路径),代码如下
小黑同学
2022/05/10
2.7K0
java selenium浏览器驱动 chromedriver放在哪里?【两种位置】
windows chromedriver 下载失败
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
云雀叫了一整天
2019/09/29
1.1K0
chromedriver 换了116的版本,还是不行?
前几天在Python最强王者群【我叫石国志】问了一个selenium使用过程中浏览器驱动报错的问题,下图是他的报错截图。
前端皮皮
2023/09/11
4650
chromedriver 换了116的版本,还是不行?
Xilinx下载器驱动提示“系统找不到指定的路径”的解决办法
本篇记录了本人解决xilinx下载器驱动安装问题(装驱动提示错误如下图)。主要过程就是更新到win10,再重装驱动即可,最后测试在Vivado2015.3中可以成功下载调试。
FPGA技术江湖
2020/12/30
1.5K0
Xilinx下载器驱动提示“系统找不到指定的路径”的解决办法
mac 搭建selenium与ChromeDriver环境安装 selenium安装 ChromeDriver验证安装
下载后,将安装包加入到环境变量。以mac系统为例,将chromedriver移至/usr/bin目录下即可
章鱼喵
2018/09/26
3.9K0
mac 搭建selenium与ChromeDriver环境安装 selenium安装 ChromeDriver验证安装
centos7安装chromedriver
2.安装chromedriver(需要下载与chrome版本匹配的安装包) 下载:https://npm.taobao.org/mirrors/chromedriver/
薛定喵君
2019/11/06
1.9K0
Mac OS环境配置chromedriver
selenium之 chromedriver与chrome版本映射表(更新至v2.29)
freesan44
2018/09/05
2.2K0
linux配置chrome和chromedriver
开始我报错是这样的:selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable may have wrong permissions
川川菜鸟
2021/10/18
1.8K0
Python 网页抓取库和框架
作为 Python 开发人员,您可以使用许多 Web 抓取工具。现在就来探索这些工具并学习如何使用它们。
用户8847084
2021/07/27
3.1K0
Web网页自动化实战《1.利用py第三方库selenium完成艺龙网访问操作》
安装python3.5以上版本,不要装最新版本,最新版本的python可能会有bug,老版本更稳定一些。
清菡
2022/06/21
7460
Web网页自动化实战《1.利用py第三方库selenium完成艺龙网访问操作》
安装Chrome(Headless)并在python中使用
Chrome(Headless)即为Chrome的Headless模式,又称为无头浏览器
wo.
2021/06/15
3.7K0
点击加载更多

相似问题

找不到硒铬驱动程序

10

硒WebDriver -找不到铬二进制

710

铬驱动器-硒

31

硒找不到chromedriver.exe

26

码头硒/节点-铬-量角器找不到铬二进制

11
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文