hand-dot / labelmake Goto Github PK
View Code? Open in Web Editor NEWlabelmake has moved and now available at pdfme / https://github.com/pdfme/pdfme
Home Page: https://labelmake.jp/javascript-pdf-generator-library
License: MIT License
labelmake has moved and now available at pdfme / https://github.com/pdfme/pdfme
Home Page: https://labelmake.jp/javascript-pdf-generator-library
License: MIT License
Hello,
When I use barcode there is not option for includeText false like bwibjs
Hi!
How you have
"engines": {
"node": "14.x"
},
Does this mean that the package is incompatible with other versions?
If not, is it possible to replace the entry with ">=14" or at least "14.x 16.x"?
When creating a label with the below definition, the last char of a couple of lines wraps to the next line, with the next line overlapping that last/first char.
basePdf: {width: 50, height: 25},
schemas: [
{
'order_name': {
'type': 'text',
'position': {'x': 0, 'y': 1},
'width': 49,
'height': 2,
'alignment': 'right',
'fontSize': 5,
'characterSpacing': 0,
'lineHeight': 1,
},
'message': {
'type': 'text',
'position': {'x': 2, 'y': 3},
'width': 46,
'height': 17,
'alignment': 'left',
'fontSize': 10,
'characterSpacing': 0,
'lineHeight': 1,
}
}],
};
inputs = rows.map(row => ({
order_name: row.order_name,
message: row.message,
}));
For testing:
row.order_name = ABC-1234
row.message = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec posuere nulla risus, eu suscipit ex imperdiet sed. Nam consectetur ullamcorper nibh, non.'
Resultant pdf: messages (7).pdf
Note that if font size is dropped to 9 then the issue doesn't appear, so I'm guessing it's just a magical combination of character line length and font size vs box width.
I would like to be able to add checks, enclosures, etc. to PDF items from boolean values, etc.
For this purpose, I was hoping to have the ability to add circles and lines by specifying their coordinates.
(You may be able to use images instead).
Hi, I really want to appreciate your help last time(#59).
I'd like to share my current point that I've been curious about and get your tips if possible.
The point is about generating Pdf file name depending on the request.
Do you think it is possible to change Pdf file name in accordance with changes that I intend to?
For example, in my code, the file name is fixed as "index(1, 2, ......).pdf".
My intention is to generate Pdf files having different name, every time to do "npm run generatePdf.js", automatically.
If you think the question above is not defined clearly, please feel free to require me more information.
Thanks!
Unable to insert images using the image field property - no errors issued to the console, but supplying a base64 encoded PNG results in a corrupted PDF being generated.
はじめまして。
ベースとなるPDFが横向きなのですが、MACのプレビューや以下のサービスを利用中は横向きになっているのですが、実際にコードをコピーして、node上で実行すると縦(90度回転した状態)になってしまいます。
https://labelmake.jp/javascript-pdf-generator-library/template-design/
何かオプション指定などで、横向きにすることは可能でしょうか?
node: v10.21.0
labelmake: 2.0.14
Hi, thank for your great work
do you have any plan to open source the code generator?
hi, I just want to know is there any interface or methods for users to convert the window coordinates to pdf coordinates?
こちらのツール非常に興味深く触らせていただいています。
https://labelmake.jp/javascript-pdf-generator-library/template-design/
こちらのデザインツールのサンプルコードなどはありますでしょうか?
It would be amazing if you could add vector svg to the document, as jsPDF does.
初めまして。
こちらのライブラリを利用させていただきたくデモページを拝見しましたが、日本語を扱うと以下のエラーが出力されます。
Uncaught (in promise) Error: WinAnsi cannot encode "あ"
APIリファレンスを参考に、以下のようにArrayBufferをパラメータに与えても同様のエラーが発生するのですが、日本語フォントには対応していますでしょうか?
もしこちらの実装方法に誤りがありましたら、ご教示いただけますと幸いです。
const font = await fetch("https://fonts.gstatic.com/s/opensans/v17/mem8YaGs126MiZpBA-UFVZ0e.ttf").then((res) => res.arrayBuffer())
const pdf = await labelmake({ template, inputs, font });
お世話になります。
日本語フォントですとこの様なエラーが出ますが対処方法ありますでしょうか?
コード上ではこんなエラーが出ます。
const labelmake = require('labelmake');
const fs = require('fs');
(async () => {
// You can also use Uint8Array or ArrayBuffer as a basePdf
const basePdf = fs.readFileSync("./template/tmp.pdf")
// const basePdf = await fetch("path/to/your.pdf").then((res) => res.arrayBuffer());
const template = {
"basePdf": basePdf,
"schemas": [
{},
{
"name": {
"type": "text",
"position": {
"x": 122.24,
"y": 136.02
},
"width": 68.6,
"height": 7,
"alignment": "left",
"fontSize": 12,
"characterSpacing": 0,
"lineHeight": 1
}
}
]
};
const inputs = [{"name":"東京都中野区"}];
const pdf = await labelmake({ template, inputs });
// Node
fs.writeFileSync('./output/new.pdf', pdf);
// Browser
// const blob = new Blob([pdf.buffer], { type: "application/pdf" });
// document.getElementById("iframe").src = URL.createObjectURL(blob);
})();
debug> c
< (node:17516) UnhandledPromiseRejectionWarning: Error: WinAnsi cannot encode "京" (0x4eac)
< at tr.encodeUnicodeCodePoint (/Users/username/workspace/test/cloudsign/node_modules/labelmake/dist/labelmake.min.js:15:180806)
< at e.encodeTextAsGlyphs (/Users/username/workspace/test/cloudsign/node_modules/labelmake/dist/labelmake.min.js:15:229123)
< at e.widthOfTextAtSize (/Users/username/workspace/test/cloudsign/node_modules/labelmake/dist/labelmake.min.js:15:228148)
< at e.widthOfTextAtSize (/Users/username/workspace/test/cloudsign/node_modules/labelmake/dist/labelmake.min.js:15:353823)
< at /Users/username/workspace/test/cloudsign/node_modules/labelmake/dist/labelmake.min.js:15:1869920
< at Array.reduce (<anonymous>)
< at r (/Users/username/workspace/test/cloudsign/node_modules/labelmake/dist/labelmake.min.js:15:1869880)
< at /Users/username/workspace/test/cloudsign/node_modules/labelmake/dist/labelmake.min.js:15:1870087
< at Array.forEach (<anonymous>)
< at /Users/username/workspace/test/cloudsign/node_modules/labelmake/dist/labelmake.min.js:15:1869795
< (node:17516) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
< (node:17516) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
< Waiting for the debugger to disconnect...
Hey! Thanks for this awesome library. Unfortunately there's a bug in fontkit when subset embedding certain fonts. I've created an issue on the "pdf-lib" repository (Hopding/pdf-lib#664) but it looks like it's not likely to be fixed anytime soon. Could you provide an option to not subset the font when embedding it? That would really help us out.
Hi, I am much obliged to you for developing this kind of library.
It is very useful to make PDF from JS.
I have a question.
Can the library generate .jpg file through your library instead of PDF?
Sometimes my user requires the document with jpg type..!
Best wishes.
to use some types, you have to import them from dist, which is not correct.
eg:
import type { TemplateSchema } from 'labelmake/dist/types/type';
Could you export the utility types outside so they can be used?
Personally, types TemplateSchema
and Template
are important to us.
Updating from v 2.0.17 causes an error trying to generate PDFs on browser using typescript + webpack5.
Error got from browser console:
labelmake default.toBuffer is not a function
I was having a schemas of
"schemas": [
{
"Logo": {
"type": "image",
"position": {
"x": 130,
"y": 45.25
},
"width": 30,
"height": 30,
"alignment": "center",
"fontSize": 14,
"characterSpacing": 0,
"lineHeight": 1,
"fontColor": ""
}
]
const inputs = [{"Logo": }]
And I am trying to add a file in the local folder. How should I put the field of Logo in the inputs, so that I can put a local image into it?
Using the simple demo from the official webside:
import labelmake from "labelmake"
import { Template } from "labelmake/dist/types/type"
export const makePdf = async () => {
const template: Template = {
basePdf: { width: 210, height: 297 },
schemas: [
{
field1: {
position: { x: 20, y: 20 },
width: 50,
height: 50,
fontSize: 30,
type: "text"
},
field2: {
position: { x: 20, y: 35 },
width: 50,
height: 50,
fontSize: 20,
type: "text"
}
}
]
}
const inputs = [
{ field1: "aa", field2: "aaaaaaaaaaaa" },
{ field1: "bb", field2: "bbbbbbbbbbbb" }
]
const pdf = await labelmake({ template, inputs })
}
When running npm start:
Starting the development server...
<--- Last few GCs --->
[19636:0000020587757D70] 32697 ms: Scavenge 4043.8 (4135.2) -> 4036.8 (4135.5) MB, 4.5 / 0.0 ms (average mu = 0.225, current mu = 0.149) allocation failure
[19636:0000020587757D70] 35426 ms: Mark-sweep 4046.1 (4137.5) -> 4037.4 (4137.5) MB, 2724.3 / 0.0 ms (average mu = 0.138, current mu = 0.045) allocation failure scavenge might not succeed
<--- JS stacktrace --->
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
1: 00007FF7D33C401F v8::internal::CodeObjectRegistry::~CodeObjectRegistry+112511
2: 00007FF7D3353146 DSA_meth_get_flags+65542
3: 00007FF7D3353FFD node::OnFatalError+301
4: 00007FF7D3C85ADE v8::Isolate::ReportExternalAllocationLimitReached+94
5: 00007FF7D3C7000D v8::SharedArrayBuffer::Externalize+781
6: 00007FF7D3B135FC v8::internal::Heap::EphemeronKeyWriteBarrierFromCode+1468
7: 00007FF7D3B202A9 v8::internal::Heap::PublishPendingAllocations+1129
8: 00007FF7D3B1D27A v8::internal::Heap::PageFlagsAreConsistent+2842
9: 00007FF7D3B0FEF9 v8::internal::Heap::CollectGarbage+2137
10: 00007FF7D3B0E0B0 v8::internal::Heap::AllocateExternalBackingStore+2000
11: 00007FF7D3B329E6 v8::internal::Factory::NewFillerObject+214
12: 00007FF7D3865C25 v8::internal::DateCache::Weekday+1797
13: 00007FF7D3D134B1 v8::internal::SetupIsolateDelegate::SetupHeap+494417
14: 0000020589D45C4B
const pdf = await labelmake({ template, inputs })
(but keeping the import) avoids the crash and allows the app to compile.Not sure if the error is related to create-react-app or to webpack 5 in general.
Hi, could you clarify how to use specific symbols like: ⌀ diameter
Use case 1:
Use case 2:
const schemas = [
{
basePDF:frontPageLayout,
fieldOne,
fieldTwo
},
{
basePDF:regularPageLayout,
fieldThree,
fieldFour,
fieldFive
}
];
const template = {[basePdf,] schemas, fontName};
labelmake({template, inputs, font})
Use case:
There are many direct applications possible with this feature (similar to how text flows in Adobe Indesign), the main obvious one is to create columns.
const schemas = {
imageField,
titleField,
leftColumnTextField,
centerColumnTextField,
rightColumnTextField,
chainedTextFields: [
{
chainName: "main-columns",
fields: [
leftColumnTextField,
centerColumnTextField,
rightColumnTextField
]
}
]
}
my first browser is Firefox and don't work on it, it work ok in chrome
Hi, I am so glad to say thank you for your efforts.
This is amazingly comfortable when I produce PDF file with prepared-PDF template.
However, I have had a trouble with input data in Korean.
I mean, whenever I have tried to set data written by Korean to the field, the error occured,
"(node:69032) UnhandledPromiseRejectionWarning: Error: WinAnsi cannot encode "왜" (0xc65c)"
I really want to discuss this issue with you.
I will share the code I have tried through github.
Hello, Thanks for this package. It's very useful.
I have a problem with barcode when use plain JS with CDN.
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'toBuffer')
Code to reproduce error.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Labelmake QRCODE</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/labelmake.min.js"></script>
</head>
<body>
<iframe id="iframe" src="" frameborder="0" style="width: 100%; height: 100vh;"></iframe>
<script>
(async () => {
const template = {
basePdf: { width: 210, height: 297 },
schemas: [
{
qrcode: {
type: "qrcode",
position: { x: 5, y: 5 },
width: 30,
height: 30
}
}
]
};
// Please omit the barcode checksum.
const inputs = [
{ qrcode: "test" }
];
const pdf = await labelmake({ template, inputs });
const blob = new Blob([pdf.buffer], { type: "application/pdf" });
document.getElementById("iframe").src = URL.createObjectURL(blob);
})();
</script>
</body>
</html>
I tested on chrome/firefox/safari, same error.
This environment work perfectly with type text
.
Thanks
Hello,
when I create a new field with "image" as type I can't put any image.
hi, I have my own case running successfully, but on the page I cannot see the edit panel.
[ ]
[ ]
It can use this library to achieve this issue.
https://github.com/Automattic/node-canvas
https://github.com/hand-dot/labelmake/blob/v2.0.15/src/type.ts#L17-L30
↑をexportしてもらいたいです。
理由は
typescriptで下記のような形で定義する場合にエラーとなるため。
import labelmake from 'labelmake'
import type { Template } from 'labelmake/dist/types/type'
import opentype from 'opentype.js'
const generatePdf = async (): Promise<Blob> => {
const fontFamilyName = 'NotoSansCJKjp'
const fontStyleName = 'Medium'
const [font, basePdf] = await Promise.all([
fetch(`/fonts/otf/${fontFamilyName}-${fontStyleName}.otf`).then((res) =>
res.arrayBuffer(),
),
fetch('/base.pdf').then((res) => res.arrayBuffer()),
])
const schemas = [
{
顧客名: {
type: 'text',
position: {
x: 17,
y: 32.49,
},
width: 82.75,
height: 7.55,
alignment: 'center',
fontSize: 11,
characterSpacing: 0,
lineHeight: 1,
},
見積No: {
type: 'text',
position: {
x: 37,
y: 62.5,
},
width: 75.13,
height: 5.58,
alignment: 'left',
fontSize: 10,
characterSpacing: 0,
lineHeight: 1,
},
納期: {
type: 'text',
position: {
x: 37,
y: 68.5,
},
width: 75.13,
height: 5.58,
alignment: 'left',
fontSize: 10,
characterSpacing: 0,
lineHeight: 1,
},
納品場所: {
type: 'text',
position: {
x: 37,
y: 74.5,
},
width: 75.13,
height: 5.58,
alignment: 'left',
fontSize: 10,
characterSpacing: 0,
lineHeight: 1,
},
取引方法: {
type: 'text',
position: {
x: 37,
y: 80.5,
},
width: 75.13,
height: 5.58,
alignment: 'left',
fontSize: 10,
characterSpacing: 0,
lineHeight: 1,
},
有効期限: {
type: 'text',
position: {
x: 37,
y: 86.5,
},
width: 75.13,
height: 5.58,
alignment: 'left',
fontSize: 10,
characterSpacing: 0,
lineHeight: 1,
},
},
]
const inputs: Record<string, string>[] = [
{
見積No: '1234567890',
顧客名: 'テスト会社',
納期: 'データ入稿日より3営業日',
納品場所: '北海道',
取引方法: '原則としてご⼊⾦確認後の納品となります。',
有効期限: '2020年 2⽉ 29⽇',
},
]
const allStrings = inputs.reduce((acc, cur) => {
Object.keys(cur).forEach((key) => {
cur[key].split('').forEach((str) => {
acc.add(str)
})
return acc
}, acc)
return acc
}, new Set<string>())
const subset = generateSubsetFont(
{ font, familyName: fontFamilyName, styleName: fontStyleName },
allStrings,
)
const template: Template = {
schemas,
basePdf,
fontName: fontFamilyName,
}
const { buffer } = await labelmake({
template,
inputs,
font: {
[`${fontFamilyName}`]: {
data: subset,
subset: false,
},
},
})
const blob = new Blob([buffer], { type: 'application/pdf' })
return blob
}
const generateSubsetFont = (
fontObj: { font: ArrayBuffer; familyName: string; styleName: string },
useStrings: Set<string>,
): ArrayBuffer => {
const font = opentype.parse(fontObj.font)
const subsetGlyphs = font.stringToGlyphs([...useStrings].join(''))
const subset = new opentype.Font({
familyName: fontObj.familyName,
styleName: fontObj.styleName,
unitsPerEm: font.unitsPerEm,
ascender: font.ascender,
descender: font.descender,
glyphs: subsetGlyphs,
})
return subset.toArrayBuffer()
}
上記で発生するエラー
const template: Template = {
schemas, // <- Type Error: The expected type comes from property 'schemas' which is declared here on type 'Template'
basePdf,
fontName: fontFamilyName,
}
該当部分のコードを下記のようにすればエラーは回避出来るけれども、
const template: Template = {
schemas,
basePdf,
fontName: fontFamilyName,
} as Template
schemas
の定義に型追加して、下記のように出来たほうが好ましいので。
import type { Template, TemplateSchema } from 'labelmake/dist/types/type'
...
const schemas: Record<string, TemplateSchema>[] = [
...
]
...
const template: Template = {
schemas,
basePdf,
fontName: fontFamilyName,
}
...
Related to #50
Use cases:
const schemas = [{
mainTextField: {
overflowOnNextPage: {Boolean},
removeFromNextPage: {Boolean},
type,
width, // required to work
height, // required to work
position,
rotate,
alignment,
fontName,
fontSize,
fontColor,
backgroundColor,
characterSpacing,
lineHeight
}
}];
const schemas = [{
enableOverflowOnNextPage: {Boolean},
mainTextField
}];
Similar to #50, labelmake does not necessery need to be aware that there is a relationship between pages. Processing each page in series, after processing page A and finding out that mainTextField
is overflown with overflowOnNextPage
set to true, then, label make can copy the source schema, remove the fields with removeFromNextPage
==true, replace the text with the remaining overflowing text and add this copied modified schema next in the queue. This will repeat until there is no overflow.
Saves size with lots of unused code
Hi, I wanted to load template I did yesterday and modify it slightly but opening it via Load button doesn't do anything and there is no error in the console.
https://labelmake.jp/javascript-pdf-generator-library/template-design/
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.