DataTables image (or at least image title) export to PDF

孤人 提交于 2019-12-06 07:44:56

问题


Using DataTables and Buttons (NOT TableTools, which is retired) extension. Some cells have progressbars and small icons. Is there a way to export these images (or at least their titles) to PDF? Found some possible hacks on this page, but all of them were for retired TableTools.

Checked https://datatables.net/reference/button/pdf and https://datatables.net/reference/api/buttons.exportData%28%29 but couldn't find any method to achieve this goal. Tested by adding this code:

stripHtml: false

but whole HTML code (like img src=...) was included in PDF file instead of images.

If exporting images isn't possible, is there a way to export at least alt or title attribute of each image? That would be enough.


回答1:


I assume you are using pdfHtml5. dataTables is using pdfmake in order to export pdf files. When pdfmake is used from within a browser it needs images to be defined as base64 encoded dataurls.

Example : You have rendered a <img src="myglyph.png"> in the first column of some of the rows - those glyphs should be included in the PDF. First create an Image reference to the glyph :

var myGlyph = new Image();
myGlyph.src = 'myglyph.png';

In your customize function you must now

1) build a dictionary with all images that should be included in the PDF
2) replace text nodes with image nodes to reference images

buttons : [
    { 
    extend : 'pdfHtml5',
    customize: function(doc) {

        //ensure doc.images exists
        doc.images = doc.images || {};

        //build dictionary
        doc.images['myGlyph'] = getBase64Image(myGlyph);
        //..add more images[xyz]=anotherDataUrl here

        //when the content is <img src="myglyph.png">
        //remove the text node and insert an image node
        for (var i=1;i<doc.content[1].table.body.length;i++) {
            if (doc.content[1].table.body[i][0].text == '<img src="myglyph.png">') {
                delete doc.content[1].table.body[i][0].text;
                doc.content[1].table.body[i][0].image = 'myGlyph';
            }
        }
    },
    exportOptions : {
        stripHtml: false
    }
}

Here is a an example of a getBase64Image function

function getBase64Image(img) {
    var canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;
    var ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0);
    return canvas.toDataURL("image/png");
}

If you just want to show the title of images in the PDF - or in any other way want to manipulate the text content of the PDF - then it is a little bit easier. The content of each column in each row can be formatted through the exportOptions.format.body callback :

buttons : [
    { 
    extend : 'pdfHtml5',
    exportOptions : {
        stripHtml: false
        format: {
            body: function(data, col, row) {
                var isImg = ~data.toLowerCase().indexOf('img') ? $(data).is('img') : false;
                if (isImg) {
                    return $(data).attr('title');
                }
                return data;
            }
        }
    }
]

The reason format.body cannot be used along with images is that is only let us pass data back to the text node part of the PDF document.

See also

  • http://pdfmake.org/#/gettingstarted (look for Images section)
  • https://github.com/bpampuch/pdfmake/blob/master/examples/images.js



回答2:


Since no suggestions received, I had to make a hack in order to get PDF file formatted the way I want.

In case someone has the same issue, you can use hidden span to display image alt/title near image itself. I'm sure it's not the best practice, but it will do the trick. So the code will look like:

<img src='image.png' alt='some_title'/><span class='hidden'>some_title</span>

This way datatables will show only the image, while PDF file will contain text you need.




回答3:


In addition to davidkonrad's answer. I created dynamically all base64 images and used them in Datatables pdfmake like this:

for (var i = 1; i < doc.content[2].table.body.length; i++) {
    if (doc.content[2].table.body[i][1].text.indexOf('<img src=') !== -1) {
        html = doc.content[2].table.body[i][1].text;

        var regex = /<img.*?src=['"](.*?)['"]/;
        var src = regex.exec(html)[1];


        var tempImage = new Image();
        tempImage.src = src;

        doc.images[src] = getBase64Image(tempImage)

        delete doc.content[2].table.body[i][1].text;
        doc.content[2].table.body[i][1].image = src;
        doc.content[2].table.body[i][1].fit = [50, 50];
    }

    //here i am removing the html links so that i can use stripHtml: true,
    if (doc.content[2].table.body[i][2].text.indexOf('<a href="details.php?') !== -1) {
        html = $.parseHTML(doc.content[2].table.body[i][2].text);
        delete doc.content[2].table.body[i][1].text;
        doc.content[2].table.body[i][2].text = html[0].innerHTML;
    }

}


来源:https://stackoverflow.com/questions/35090747/datatables-image-or-at-least-image-title-export-to-pdf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!