在使用jspdf时转换/规范特殊字符

5
尝试使用 jspdf lib @1.4.1 将文本转换为 pdf 时,输出有时会变得非常丑陋和难以阅读,因为文本包含一些特殊字符,例如:

左单引号 U+2018,或右单引号 U+2019,或符号如 ,或者在 Kadıköy 中的 ı... 我该如何清理/标准化这些文本?或者在 jspdf 中是否有任何选项可用于解决此问题?

更新:

要重现问题,只需在此示例 https://parall.ax/products/jspdf 的第 9 行中使用此字符串:'→Kadıköy',您将看到箭头被转换为 !' ı 被转换为 1

(FYI,Kadıköy是一座城市的名称https://en.wikipedia.org/wiki/Kad%C4%B1k%C3%B6y

3个回答

5

我们可以在这里阅读到:

jsPDF通过具有使用自定义字体的功能,最终支持UTF-8。

您面临的问题是您并不真正了解PDF的工作原理。它必须拥有一些能够显示正确字母的字体。它必须是一个系统字体(用于PDF阅读器)或嵌入字体。对于每个单独的字母,PDF必须拥有一个正确的字体。在这种情况下,对于同一PDF中的新语言中的每个单词,都必须设置正确的字体

一些TTF字体是为某些特定字母创建的,但并非所有TTF都是正确创建的,因为背后有一种标准技术另外,并非所有为某些特定字母创建的TTF字体都可以在PDF中显示它们。例如,我在互联网上找到的“天城文”字体应支持所有印地语字母,但完全失败了。

也需要找到正确的TTF字体。我已经找到了 - 在您的情况下,对于字符串“‘→Kadıköy’”,您可以使用“Courier New”或“Arial Unicode MS”。
我已经为您的任务中的每个字母搜索并找到以下列表:
→ - {{link1:“向右箭头”(u+2192)的字体支持}}
ı - {{link2:“拉丁小写字母无点I”(u+0131)的字体支持}}
‘ - {{link3:“左单引号”(u+2018)的字体支持}}
’ - {{link4:“右单引号”(u+2019)的字体支持}}

ö - 支持“带分音符的拉丁小写字母o”(u+00F6)的字体

大部分语言的解决方案

我创建了一个应用程序,可以为世界上大多数语言创建PDF文件。

如何使用:

  1. 首先下载并提取免费的TTF字体“Arial Unicode MS
  2. 启动下面的代码段,并从您的文件夹中选择提取的免费TTF字体“Arial Unicode MS”。
  3. 使用您的语言编写文本,然后单击“创建PDF”按钮。
  4. PDF将被下载,您可以打开它。
在某些情况下,您的语言可能不受TTF字体“Arial Unicode MS”的支持。您可以在这里找到支持的语言列表。在这种情况下,您需要从正确的TTF字体中找到一个。但要小心:如果字体小于100 kb,则会发现它无法与jsPDF一起使用(请参见我的帖子开头)。 应用程序

var fontInBase64 = '',
    fileName = '',
    message = document.querySelector('div'),
    txtForPdf = document.querySelector('textarea'),
    errorStr = '<b style="color:red">Please select a font file!</b>';

function readFile()
{
    var file = document.querySelector('input[type=file]').files[0],
        reader = new FileReader();

    if(file && file.name.split('.')[1].toLowerCase() != 'ttf')
    {
        message.innerHTML = errorStr;
        return;
    }

    if(txtForPdf.value.replace(/\s+/g, '').length < 1)
    {
        message.innerHTML = '<b style="color:red">Please write some Text!</b>';;
        return;
    }

    reader.onloadend = function()
    {
        fontInBase64 = reader.result.split(',')[1];
        fileName = file.name.replace(/\s+/g, '-');

        createPDF(fileName, fontInBase64);
    }

    if(file) reader.readAsDataURL(file);
    else message.innerHTML = errorStr;
}


function createPDF(fileName, fontInBase64)
{
    var doc = new jsPDF('p','mm','a4');
        fileNameWithoutExtension = fileName.split('.')[0],
        lMargin = 15, // left margin in mm
        rMargin = 15, // right margin in mm
        pdfInMM = 210; // width of A4 in mm

    doc.addFileToVFS(fileName, fontInBase64);
    doc.addFont(fileName, fileNameWithoutExtension, 'normal');

    doc.setFont(fileNameWithoutExtension);
    doc.setFontSize(14);
    var splitParts = doc.splitTextToSize(txtForPdf.value, (pdfInMM - lMargin - rMargin));
    doc.text(15, 15, splitParts);

    doc.save('test.pdf');
}

function setHindiToTextArea()
{
    txtForPdf.value =
    "हिन्दी विश्व की एक प्रमुख भाषा है एवं भारत की राजभाषा है। केंद्रीय स्तर पर भारत में दूसरी आधिकारिक भाषा अंग्रेजी है। यह हिन्दुस्तानी भाषा की एक मानकीकृत रूप है जिसमें संस्कृत के तत्सम तथा तद्भव शब्द का प्रयोग अधिक हैं और अरबी-फ़ारसी शब्द कम हैं। हिन्दी संवैधानिक रूप से भारत की प्रथम राजभाषा और भारत की सबसे अधिक बोली और समझी जाने वाली भाषा है। हालांकि, हिन्दी भारत की राष्ट्रभाषा नहीं है क्योंकि भारत का संविधान में कोई भी भाषा को ऐसा दर्जा नहीं दिया गया था। चीनी के बाद यह विश्व में सबसे अधिक बोली जाने वाली भाषा भी है। विश्व आर्थिक मंच की गणना के अनुसार यह विश्व की दस शक्तिशाली भाषाओं में से एक है। हिन्दी और इसकी बोलियाँ सम्पूर्ण भारत के विविध राज्यों में बोली जाती हैं। भारत और अन्य देशों में भी लोग हिन्दी बोलते, पढ़ते और लिखते हैं। फ़िजी, मॉरिशस, गयाना, सूरीनाम की और नेपाल की जनता भी हिन्दी बोलती है। 2001 की भारतीय जनगणना में भारत में ४२ करोड़ २० लाख लोगों ने हिन्दी को अपनी मूल भाषा बताया। भारत के बाहर, हिन्दी बोलने वाले संयुक्त राज्य अमेरिका में 648,983; मॉरीशस में ६,८५,१७०; दक्षिण अफ्रीका में ८,९०,२९२; यमन में २,३२,७६०; युगांडा में १,४७,०००; सिंगापुर में ५,०००; नेपाल में ८ लाख; जर्मनी में ३०,००० हैं। न्यूजीलैंड में हिन्दी चौथी सर्वाधिक बोली जाने वाली भाषा है";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.4.1/jspdf.min.js" crossorigin="anonymous"></script>
<input type="file" onchange="message.innerHTML='&nbsp;'"><br><br>
<textarea rows="4" cols="75">‘→Kadıköy’</textarea>
<div>&nbsp;</div>
<input type="button" value="Create PDF with UTF support" onclick="readFile()">
<br>
<i>For example</i>:<br><a href="#" onclick="setHindiToTextArea()"><b>Click on this line if you wont to set hindi text to the textarea.</b></a>


1
@Bonnard,在你的情况下,我建议你使用“Courier New”而不是“Arial Unicode MS”,因为“Courier New”支持所有的字母,而“Arial Unicode MS”也支持,但它太大了。你可以在系统字体中找到“Courier New”。请将这个字体复制到另一个文件夹中,然后通过选择这个字体来访问它。 - Bharata
你好,如何在jspdf中使用utf8来处理法语特殊字符? - Imen

4
你可以通过导入支持特殊字符的字体来实现。从examples上的basic.js,你可以看到如何应用它。(示例带有西里尔字母)。
function demoUsingTTFFont() {
    //https://fonts.google.com/specimen/PT+Sans
    var PTSans = “...... “); // place long string of text here
    var doc = new jsPDF();

    doc.addFileToVFS("PTSans.ttf", PTSans);
    doc.addFont('PTSans.ttf', 'PTSans', 'normal');

    doc.setFont('PTSans'); // set font
    doc.setFontSize(10);
    doc.text("А ну чики брики и в дамки!", 10, 10);

    doc.save('test.pdf');
}

作为字体系列,请查看谷歌的Noto
来源:https://github.com/MrRio/jsPDF/issues/12(向下滚动)

这根本没有解决问题。 - Bonnard
这是我能找到的唯一解决方法,有很多帖子没有这个解决方法,而是告诉你要更改使用的库。也许在这种情况下我的建议无用。 - mico
我不理解:var PTSans = “......“); // 在此处放置长字符串 - educob
请查看上面@Igor的回答。有一个Fiddle示例。 - mico

3

我认为,Mico的回答是正确的,只需要用你使用的字体(base64编码)替换PTSans字体即可。 请参见jsfiddle:https://jsfiddle.net/o0m9pzyv/12/

var PTSans = ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接