hhurz / tableExport.jquery.plugin

jQuery plugin to export a html table to JSON, XML, CSV, TSV, TXT, SQL, Word, Excel, PNG and PDF
MIT License
984 stars 714 forks source link

Korean pdf output is broken (UTF-8) #363

Closed jdh6658 closed 1 year ago

jdh6658 commented 1 year ago

I am using this in my bootstrap table using Korean(Utf-8). However, if there is Korean in the table, there is an error that Korean is not displayed normally when exported using jsPDF. I didn't modify anything in the default file tableExport (4).pdf

hhurz commented 1 year ago

The tableExport plugin uses jsPDF as PDF producer. It is a known issue of that plugin, that it has no real unicode support. Only a few unicode characters (as german umlauts) are supported. Please see https://github.com/MrRio/jsPDF/issues/13, https://github.com/MrRio/jsPDF/issues/12 and https://github.com/MrRio/jsPDF/issues/115 for more information about that problem.

You can try replacing jsPDF with pdfmake. There is a working example for Chinese that should give you an idea of how to do it. But to be honest, it won't be easy. You first need to create a Korean font file for pdfmake (see here, for which you need a suitable Korean font (ttf or ttc). Which font is suitable for this, I can't say.

jdh6658 commented 1 year ago

Thanks for your comment. But pdfmaker is not working and get error [ Uncaught (in promise) Error: File 'Roboto-Medium.ttf' not found in virtual file system VM97436 pdfmake.min.js:2]

So i found way to use jsPDF. And I confirmed that the Korean language appears normally in jsPDF with the following code.

<script>
var _fonts="...";//Base64 encoded font
var doc = new jsPDF("p", "mm", "a4");
doc.addFileToVFS('malgun.ttf', _fonts);  //
doc.addFont('malgun.ttf','malgun', 'nomal');
doc.setFont('malgun'); 

doc.text(15, 40, '안녕하세요'); // 
doc.save('web.pdf');
</script>

I don't know where to add this code to tableExport.js file. Can you tell me where should I add this code in tableexport.js file? I tried adding it in several places, but it didn't work. I'm still immature so I can't figure out why

hhurz commented 1 year ago

Thanks for figuring this out! You could try it as in the example below without having to modify tableexport.js:

<!DOCTYPE html>
<html lang=zh>
  <head>
    <meta charset="utf-8">
    <title>Issue 363: korean is broken</title>

    <script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script type="text/javascript" src="../libs/FileSaver/FileSaver.min.js"></script>
    <script type="text/javascript" src="../libs/jsPDF/jspdf.umd.min.js"></script>
    <script type="text/javascript" src="../tableExport.js"></script>

    <style type="text/css">
      <!--
      caption {
        font-size: 1em;
        white-space: nowrap;
        text-align: left;
      }

      table  {
        border-collapse: collapse;
        margin-top: 2em;
      }

      table > thead > tr > td,
      table > thead > tr > th {
        background-color: gray;
        border: 1px solid #efefef;
        color: white;
        padding: 0.2rem;
      }

      table > tbody > tr > td {
        border: 1px solid #999;
        padding: 0.2rem;
      }
      -->
    </style>

    <script type="text/javaScript">
      function doExport(selector, params) {
        var options = {
          tableName: 'Table name'
        };

        $.extend(true, options, params);
        $(selector).tableExport(options);
      }

    function doDocCreated(doc) {
      // In the next line replace <base64> with a base64 encoded font, 
      // e.g GowunDodum-Regular.ttf from Google Fonts family "Gowun Dodum".
      // To do this, you need to upload your Korean font to a Base64 file encoder 
      // and use its output in place of <base64> while preserving the apostrophes
      // so it would look similar like this:
      // const _fonts = "AAEAAAAQAQAABAAAR0RFRtwiqrwAAAIUAAABzEdQT1OlZYtBA ... sBHBcKLy4BERYQAR4VAAAA";
      const _fonts = "<base64>";

      if (_fonts === "<base64>") {
        alert ("Missing base64 encoded font, e.g GowunDodum-Regular.ttf");
        return;
      }

      doc.addFileToVFS('GowunDodum-Regular.ttf', _fonts);
      doc.addFont('GowunDodum-Regular.ttf', 'GowunDodum-Regular', 'normal');
      doc.setFont('GowunDodum-Regular'); 

      doc.text(15, 120, '안녕하세요'); // Example text output
    }

  </head>
  <body>
    <p>
    <a href="#" onClick="doExport('#issue363', {
                                   type: 'pdf',
                                   jspdf: {orientation: 'l',
                                           onDocCreated: doDocCreated,
                                           autotable: {startY: 10,
                                                       margin: {left: 10, top: 10},
                                                       pageBreak: 'avoid'
                                                      }
                                          }
                                  });">
    <img src='icons/pdf.png' alt="PDF" style="width:24px"> PDF (jsPDF)</a>
    </p>
    <table id="issue363" class="">
      <caption>Issue 363: Korean pdf export</caption>
      <thead>
      <tr>
        <th>안녕하세요</th>
        <th>안녕하세요</th>
        <th>안녕하세요</th>
      </thead>
      <tbody>
        <tr>
          <td>안녕하세요</td><td>안녕하세요</td><td>안녕하세요</td>
        </tr>
        <tr>
          <td>안녕하세요</td><td>안녕하세요</td><td>안녕하세요</td>
        </tr>
        <tr>
          <td>안녕하세요</td><td>안녕하세요</td><td>안녕하세요</td>
        </tr>
      </tbody>
    </table>
  </body>
</html>
hhurz commented 1 year ago

FYI: I just released a fix (release 1.27.0) with which the above example works. Thanks again for your contribution. With this procedure it should now be possible to export HTML tables to PDF even for other country languages which are not natively supported by jsPDF.