在 node.js 服务器上更改 svg 中文本元素的内容

Change content of text elements in svg on a node.js server

我在节点/快速服务器上使用 svg.jssvgdom 来尝试操作 svg,然后将其转换为 PNG 以构建 PDF。

目前,我已经做到了这一点

const window = require('svgdom');
const SVG = require('svg.js')(window);
const document = window.document;
const draw = SVG(document.documentElement);
const fs = require('fs');
const tag = fs.readFileSync(`images/name-tag-1-with-name.svg`,'utf8');
const svg = draw.svg(tag);

这是 SVG 的布局

<svg id="name-tag" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 216 288">
  <defs>
    <style>
      .cls-1,
      .cls-2 {
        fill: #414042;
      }

      .cls-2 {
        opacity: 0.95;
      }

      .cls-3,
      .first-name,
      .last-name {
        fill: #fff;
      }

      .cls-4 {
        fill: none;
        stroke: #fff;
        stroke-miterlimit: 10;
      }

      .first-name,
      .last-name {
        font-size: 30.87px;
        font-family: Gibson-SemiBold, Gibson;
        font-weight: 700;
      }

      .cls-6 {
        letter-spacing: -0.01em;
      }

      .last-name {
        letter-spacing: -0.01em;
      }

      .cls-8 {
        letter-spacing: 0em;
      }
    </style>
  </defs>
  <polygon class="cls-1" points="0 0 0 288 216 0 0 0" />
  <polygon class="cls-2" points="0 288 216 288 216 0 0 288" />
  <polygon class="cls-3" points="119.35 66.27 109.12 17.38 98.95 66.02 72.4 85.51 72.4 101.58 72.41 101.61 109 74.78 145.5 101.58 145.5 85.45 119.35 66.27"
  />
  <polygon class="cls-3" points="109 82.28 108.97 82.25 72.4 109.08 72.4 125.15 72.41 125.19 109 98.37 145.5 125.15 145.5 109.04 109 82.25 109 82.28"
  />
  <polygon class="cls-3" points="109 105.85 108.97 105.83 72.4 132.66 72.4 148.75 72.41 148.77 109 121.95 145.5 148.75 145.5 132.63 109 105.83 109 105.85"
  />
  <line class="cls-4" x1="11.95" y1="183" x2="206.53" y2="183" />
  <text class="first-name" transform="translate(76.22 228.16)">
    First
  </text>
  <text class="last-name" transform="translate(47.47 266.32)">
    Last
  </text>
</svg>

我看到有一个接受索引的 get() 方法,但我能得到第一个文本元素的唯一方法是这样的...

const fName = svg.get(2).get(8)

我不确定为什么必须先 select 第二个元素,然后才是我要获取的元素的实际索引

此外,我不确定我对 set 做了什么,这正是 .select() 方法应该 return,我可以 select 文本带有 class 名称的元素以某种方式获取它的索引或以某种方式更改文本?

此时尝试更改该元素的文本也不起作用

fName.plain(firstName)

给我这个错误

TypeError: fName.plain is not a function

我只是想更改此 SVG 文件中 .first-name.last-name 文本元素的文本,然后我就可以将其传递给转换它的函数到将进入正在生成的 PDF 页面的 PNG。

任何人都可以帮助我了解如何在这个库中完成这项工作吗?我已经在这里待了几个小时

编辑

我加载了 cheerio 并能够以这种方式获取元素,但仍在努力解决如何使用它来更改文本的问题。我似乎无法从这个 still

中获得对 SVG.js 元素的引用
const cheerio = require('cheerio')
const $ = cheerio.load(tag);
const firstNameTag = $('text.first-name')
const lastNameTag = $('text.last-name')

对于您的 cheerio-edit,您可以使用

更改节点的文本内容
firstNameTag.text('This is the new first-name-text');
lastNameTag.text('This is the new last-name-text');

然后用

获取整个更新文件的字符串
const updatedSvg = $.html();

附带问题

当您将文件中的 svg 内容导入到您的 svg 中时,导入后看起来像这样:

// svg from svgdom
<svg>
    <defs>...</defs>
    // parser object, svg.js needs it
    <svg></svg>
    // imported svg
    <svg></svg>
</svg>

使用 svg.get(2) 你会得到你的 svg 实例。使用以下 get(8) 你有你的文本元素。

您从 select() 返回的 SVG.Set 或多或少是一个奇特的数组。 svg.js 在 svgjs.dev 有很好的文档,其中有很好的解释。您可以使用 get(index), first(), last().

访问集合的元素

真题解答

但是,您要实现的目标很容易。直接通过ID获取元素即可:

SVG.get('first-name').text('New text')
SVG.get('last-name').text('New text')