Search code examples
javascriptjquerylaraveldatatablespdfmake

Arabic sentence for words are reversed on datatables pdfhtml5 "pdfmake"


enter image description here

I have changed the default font to a font that supports arabic The words supposed to be shown this way:

تقارير حركة الرسائل

But they are shown as

الرسائل حركة تقارير

function processDoc(doc) {
  // https://pdfmake.github.io/docs/fonts/custom-fonts-client-side/
  pdfMake.fonts = {
    Roboto: {
      normal: 'Roboto-Regular.ttf',
      bold: 'Roboto-Medium.ttf',
      italics: 'Roboto-Italic.ttf',
      bolditalics: 'Roboto-MediumItalic.ttf'
    },
    scheherazade: {
      normal: 'Scheherazade-Regular.ttf',
      bold: 'Scheherazade-Regular.ttf',
      italics: 'Scheherazade-Regular.ttf',
      bolditalics: 'Scheherazade-Regular.ttf'
    }
  };
  // modify the PDF to use a different default font:
  doc.defaultStyle.font = "scheherazade";

}
  $(function () {
      
    var table = $('.data-table').DataTable({
        processing: true,
        serverSide: true,
        ajax: {
          url: "{{ route('messaage_movements.index') }}",
          "method": "GET",
          data: function (d) {
                d.search = $('input[type="search"]').val()
            }
        },
        
          dom: 'Bfrtip',

        buttons: [
            // {
            // extend: 'pdfHtml5',
            // text: 'PDF',
         
            // } ,
            'copyHtml5',
            'excelHtml5',
            'csvHtml5',
            'print',
            {
                extend: 'pdfHtml5',
                // download: 'open',
                 title: '{{__('messages.messaage_movements')}}',

      customize: function ( doc ) {
        processDoc(doc);
        doc.content.splice( 1, 0, {
                    margin: [ 0, 0, 0, 12 ],
                    alignment: 'right',
              } );
      },
            }
            
        ],
        columns: [
            {data: 'id', name: 'id'},
            {data: 'message', name: 'message'},
            {data: 'user_id', name: 'user_id'},
            {data: 'number_massages', name: 'number_massages'},
            {data: 'status', name: 'status'},
            {data: 'reason', name: 'reason'},
            {data: 'date_sent', name: 'date_sent'},

            {
                data: 'action', 
                name: 'action', 
                orderable: true, 
     `enter code here`           searchable: true
            },
        ]
    });
  
  });

I have followed a code like that but turned it into arabic I don't know where to put the direction="rtl" in the code cause It's not a visible html tag enter link description here

-----edit The changes I've made above solved the problem of the title and the rows but not the thead.

customize: function ( doc ) {
    processDoc(doc);
    doc.content[0]['text'] = doc.content[0]['text'].split(' ').reverse().join(' ');
  },
        }
        
    ],
    columns: [
        {data: 'id', name: 'id'},
        {data: 'message', name: 'message',targets: '_all',render: function(data, type, row) {
      if (type === 'myExport') {
        return data.split(' ').reverse().join('  ');
      }
      console.log(data);
      return data;
    }},

Solution

  • This library doesn't support rtl very well.. but you could fix this issues in table body using "render" function in columns option to reverse the content..

    the problem is with your table head, because you can't customize table header content..

    but I figured out a trick to solve this issue..

    the idea is to create two table headers.. one reversed and hidden from the html page.. while the other is not reversed and shown in html, the library will only detect the reversed one and display it in the pdf file

    to apply this just add this code to your js file..

    let thead = document.getElementsByTagName('thead')[0].children[0]
    const reversedHead = thead.cloneNode(true)
    thead.parentNode.appendChild(reversedHead)
    let headCells = reversedHead.children
    Object.keys(headCells).forEach(i=>{
        headCells[i].textContent = headCells[i].textContent.split(' ').reverse().join(' ')
    })
    reversedHead.setAttribute('hidden',"")