Changing font in datatables pdfmaker extension - pdf

I have googled enough for a whole one day, and searched StackOverflow to find a solution for changing the font in pdf exports of dataTables. However, I didn't run into a solution. When I export the table into pdf script fonts are something undecipherable. Just look at the picture below. It shows two columns from my table.
Both dataTables forum and pdfMaker documentations are vague. Can anyone please help me out of the problem. I need to specify a font for pdfMaker extension of datatables.
The following is what vfs_fonts.js looks like:
this.pdfMake = this.pdfMake || {}; this.pdfMake.vfs = {
pdfMake.fonts = {
Vazir: {
normal: 'Vazir-FD.ttf',
bold: 'Vazir-FD.ttf',
italics: 'Vazir-FD.ttf',
bolditalics: 'Vazir-FD.ttf'
}
};
}
The following is also my buttons block of my datatables:
buttons: [
{ extend: 'pdfHtml5', exportOptions:
{ columns: [0, 1, 2, 3, 4, 5, 6] },
customize: function (doc) {
doc.defaultStyle.font = Vazir},
},
]
Note that in the above block of code, when I add 'customize' block, the pdfMaker button won't prepare any pdf reports; without it, it works, however, the fonts are undecipherable.
Thanks in advance.

Here is a solution.
The DataTable Code
The HTML is as follows:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Export to PDF</title>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
<!-- buttons -->
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.6.1/css/buttons.dataTables.min.css">
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.1/js/dataTables.buttons.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.1/js/buttons.flash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
<!--
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
Build a custom local version of the vfs_fonts.js file, containing whatever fonts you need. The
structure of the file is this:
this.pdfMake = this.pdfMake || {}; this.pdfMake.vfs = {
"arial.ttf": "AAEAA...MYXRu",
"another_one.ttf": "XXXX...XXXX"
};
Replace the "AAEAA...MYXRu" with the base64-encoded string of your font file.
You can use this site to generate the string: https://dataurl.sveinbjorn.org/#dataurlmaker
-->
<script src="vfs_fonts.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.1/js/buttons.html5.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.1/js/buttons.print.min.js"></script>
</head>
<body>
<div style="margin: 20px;">
<table id="example" class="display nowrap dataTable cell-border" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Data</th>
</tr>
</thead>
<tbody>
<tr>
<td>Adélaïde Nixon</td>
<td><font face="verdana">الفبای فارسی ۱۲۳۴</font></td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Name</th>
<th>Data</th>
</tr>
</tfoot>
</table>
</div>
<script type="text/javascript">
$(document).ready(function() {
$('#example').DataTable({
dom: 'Bfrtip',
buttons: [{
extend: 'pdf',
customize: function ( doc ) {
processDoc(doc);
}
}]
});
});
function processDoc(doc) {
//
// https://pdfmake.github.io/docs/fonts/custom-fonts-client-side/
//
// Update pdfmake's global font list, using the fonts available in
// the customized vfs_fonts.js file (do NOT remove the Roboto default):
pdfMake.fonts = {
Roboto: {
normal: 'Roboto-Regular.ttf',
bold: 'Roboto-Medium.ttf',
italics: 'Roboto-Italic.ttf',
bolditalics: 'Roboto-MediumItalic.ttf'
},
arial: {
normal: 'arial.ttf',
bold: 'arial.ttf',
italics: 'arial.ttf',
bolditalics: 'arial.ttf'
}
};
// modify the PDF to use a different default font:
doc.defaultStyle.font = "arial";
var i = 1;
}
</script>
</body>
The DataTable as a Web Page
The above HTML produces the following web page:
The PDF File
When you click on the "Save as PDF" button, the PDF document looks like this:
How to Implement
As explained here, pdfMake uses the Roboto font by default. This font does not support Persian characters/script. To work around this, I changed the default font to Arial, which does provide support for Persian characters/script.
Please see the additional notes at the end regarding the use of Arial - another font may be more appropriate to avoid licensing issues.
To make this change I took the following steps:
I generated a new vfs_fonts.js file, containing the contents of an arial TTF file. I also refer to this new local vfs_fonts.js file, instead of the Cloudflare version.
The vfs_fonts.js file has the following structure:
this.pdfMake = this.pdfMake || {}; this.pdfMake.vfs = {
"arial.ttf": "AAEAA...MYXRu",
"another_one.ttf": "XXXX...XXXX"
};
Each of the "AAEAA...MYXRu strings is the base64-encoded representation of the related font file.
To generate the string for your TTF file, you can use the utilities provided by pdfmake (see below), or you can use any base64 encoder. One example is dataurlmaker.
Paste the (very long) string generated by dataurlmaker into your vfs_fonts.js file. Do NOT include any preamble provided by dataurlmaker ("data:application/octet-stream;base64,"). Include only the base64 string itself.
Alternatively...
Using the tools provided by pdfmake:
To generate this new vfs_fonts.js file, I followed the relevant instructions on this page.
(a) I already had npm installed.
(b) I ran npm install pdfmake
(c) I changed to the pdfmake installation directory:
C:\Users\<myUserID>\node_modules\pdfmake\
(d) I created the examples/fonts subdirectory in my pdfMake directory.
(e) I copied my Windows arial.ttf file into this new fonts directory.
(f) I ran npm install (from the pdfMake directory) to ensure all prerequisites modules were installed.
(g) I installed gulp using npm install gulp --global
(h) I ran gulp buildFonts to create a new build/vfs_fonts.js.
(i) I included this new build/vfs_fonts.js file in my web page code (as shown above).
After taking these steps, I was able to generate a PDF using the Arial font.
Update
Please read the comments provided by #anotherfred for some important notes:
Regarding the specific use of Arial (emphasis is mine):
Note that Arial's licence may forbid this. Fonts like Noto Sans are free international fonts but you have to carefully choose the version to get the languages you want.
You can use online tools such as Google Fonts and Font Squirrel to find fonts which match your language & character/glyph requirements.
Regarding how to reference your chosen font file(s):
Also, to avoid having to set the default font in datatables options, you can just name your key in pdfMake.fonts Roboto (whatever ttf files you actually use in it) and it will be used automatically.
It would be great if the following could be usd out-of-the-box in a future version of DataTables (with an upgraded version of pdfmake)
You can also use a font url instead of vfs_fonts, but this requires a newer version of pdfMake than datatables suggest.

Related

Export Html to Pdf using JsReport in Asp.net core

I have a html page with images, tables and some styling with Bootstrap 4. I tried to convert the pages to pdf using the JsReportMVCService, the pdf doesnot load with the proper css class from bootstrap.
HTML CONTENT
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>WeekelyReport</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
</head>
<body>
<div class="jumbotron">
<h1> Hello John Doe,</h1>
<p>
This is a generic email about something.<br />
<br />
</p>
</div>
</body>
</html>
ASP.NET CORE IMPLEMENTATION
var generatedFile = await GeneratePDFAsync(htmlContent);
File.WriteAllBytes(#"C:\temp\hello.pdf", generatedFile);
async Task<byte[]> GeneratePDFAsync(string htmlContent)
{
var report = await JsReportMVCService.RenderAsync(new RenderRequest()
{
Template = new Template
{
Content = htmlContent,
Engine = Engine.None,
Recipe = Recipe.ChromePdf
}
});
using (var memoryStream = new MemoryStream())
{
await report.Content.CopyToAsync(memoryStream);
return memoryStream.ToArray();
}
}
How my Pdf Looks after the conversion to PDF.
It is possible to convert to pdf with the same bootstrap 4 layout? or am i missing something during the conversion here?
The pdf printing uses print media type and the bootstrap has quite different styles for printing. This causes that the pdf looks different than html, but it looks the same as you would print it. I would generally not recommend using responsive css framework as bootstrap for printing static pdf, but it is of course your choice.
To make your example looking the same on pdf you just need to change the media type on the chrome settings.
var report = await JsReportMVCService.RenderAsync(new RenderRequest()
{
Template = new Template
{
Content = htmlContent,
Engine = Engine.None,
Recipe = Recipe.ChromePdf,
Chrome = new Chrome {
MediaType = MediaType.Screen,
PrintBackground = true
}
}
});
make sure you have the latest jsreport.Types#2.2.2

epub.js not loading properly on IE11

I'm trying to load an epub on my page using epub.js library and its not working on IE 11, it works perfrectly on chrome and Firefox though.
I'm not getting a script error, I don't get a message in the console log, fiddler says all scripts (including zip.js and my epub) are downloaded properly.
It just doesn't load, the iframe embedded has a src="" property and an empty html body. as in the following snapshot.
Here is my html page content:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="content/epubjs/epub.js"></script>
<script src="content/epubjs/libs/zip.min.js"></script>
</head>
<body>
<span onclick="Book.prevPage();">Prev</span>
<span onclick="Book.nextPage();">Next</span>
<div style="height: 700px; border: 5px solid red" id="area"></div>
<script type="text/javascript">
EPUBJS.filePath = "content/epubjs/libs/";
</script>
<script type="text/javascript">
var Book = ePub("content/aliceDynamic.epub", {
version: 4,
restore: false, // Skips parsing epub contents, loading from localstorage instead
storage: false, // true (auto) or false (none) | override: 'ram', 'websqldatabase', 'indexeddb', 'filesystem'
spreads: false, // Displays two columns
fixedLayout: true, //-- Will turn off pagination
styles: {}, // Styles to be applied to epub
width: false,
height: '700px'
});
Book.renderTo("area");
</script>
</body>
</html>
I tried to play around with the options parameter, set things to false and true here and there but it didn't help.
It looks like it is a problem with the current version of epub.js and internet explorer 11. If you try and load the moby dick page you should see the same problem.
Try setting a break on all exceptions (even handled ones) in the javascript engine of IE, and you will see that the javascript throws an exception saying that "'XPathResult' is undefined".
Common recommendations to correct that seem to be installing the wicked-good-xpath library in order to sidestep ie11 lack of XPath support. Install the library and initialize it before trying to load you epub.
If this doesn't correct your problem, you may have to wait until the issues are solved since you don't seem to be the only person who encounters it.

rally.sdk.ui.StandardReport.ReleaseDefectTrend does not produce accurate results outside of Rally using loginkey

I am trying to create a Release trend chart, but I am getting different results if I run the code inside a rally app versus running the app outside of rally using a valid login key. Below is the code in question.
After getting the chart to work correctly, I would love to be able to show some subset of the data, similar to the actual ReleaseDefectTrend chart inside of Rally, that lets you specifiy XXX number of days/weeks/months/etc. Are there setting(s) for the config of the chart that will allow you to do this.
Thanks in advance!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- Copyright (c) 2011 Rally Software Development Corp. All rights reserved -->
<html>
<head>
<!-- <script type="text/javascript" src="/apps/1.32/sdk.js?debug=false"></script> -->
<script type="text/javascript" src="https://rally1.rallydev.com/apps/1.32/sdk.js?loginKey=myvalidloginkeyhere"></script>
<script type="text/javascript">
function onLoad() {
//alert('ProjOID = ' + __PROJECT_OID__);
/
var rallyDataSource = new rally.sdk.data.RallyDataSource("myvalidworkspaceID","myvalidprojectID","false","false");
var ddown1=document.getElementById("ddown1");
var config = { label: "Select a release " };
var releaseDropdown = new rally.sdk.ui.ReleaseDropdown(config,rallyDataSource);
releaseDropdown.display(ddown1,releaseSelected);
}
function releaseSelected(dropdown,eventArgs) {
var selectedItem=eventArgs.item;
var selectedValue = eventArgs.value;
var releaseObjids = new Array();
releaseObjids[1]=selectedItem.ObjectID;
displayChart1(releaseObjids[1]);
}
function displayChart1(release) {
var config = {
report: rally.sdk.ui.StandardReport.ReleaseDefectTrend,
//itle: 'Technical Debt',
width : 600,
height: 250,
releases: release
};
alert('chart1 release = ' + release);
var report = new rally.sdk.ui.StandardReport(config);
var div1=document.getElementById("div1");
report.display(div1);
}
rally.addOnLoad(onLoad);
</script>
</head>
<body>
<table border="1">
<tr>
<td align="center"><div id="ddown1"></div></td>
</tr>
<tr>
<td><div id="div1"></div></td>
</tr>
</table>
</body>
</html>
Looks like there is no hardcoded Object IDs of releases in your code, and workspace is also not specified. All WS API queries are bound to a workspace, and in the absence of specified workspace and a default for a given user there is no guarantee that what you see inside Rally is going to be the same outside. To narrow this down, you do not need to use login key in this stage of troubleshooting. Please make sure the app works outside of Rally as expected - the login key only allows you to avoid the prompt to login. The scope is not specified in your code, but the app needs to pull available releases from somewhere.
Before you customize the original code found here see if the original code produces identical results for you outside and inside of Rally when you hard code Object ID of a specific release, and then move on to more complex scenarios when you have multiple ObjectIDs hardcoeded, and only then try to use a variable set dynamically from a dropdown value:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta name="Name" content="Component Example: Standard Report">
<script type="text/javascript" src="https://rally1.rallydev.com/apps/1.26/sdk.js"></script>
<script type="text/javascript">
function initPage() {
var config = {
report: rally.sdk.ui.StandardReport.ReleaseDefectTrend,
width : 800,
height: 400,
releases: [1111,2222]
};
var report = new rally.sdk.ui.StandardReport(config);
report.display("aDiv");
}
rally.addOnLoad(initPage);
</script>
</head>
<body>
<div id="aDiv"></div>
</body>
</html>
For more info see Apps Outside of Rally
Generally standard reports are canned reports and cannot be customized further outside of what the JSON configuration object allows. AppSDK1 allows you to load a report in a custom page by providing access to them via this syntax:
report: rally.sdk.ui.StandardReport.ReleaseDefectTrend
but if you want to zoom in, to display more information, perhaps in a chart, this has to be coded from scratch.

jquery-ui progressbar not showing

I'm trying to add a simple progress bar to my application in rails using jquery-ui. I'm following this example: http://jqueryui.com/progressbar/
I create the div
<div id="progressbar"></div>
and in my JS I have
$(document).ready( function() {
$("#progressbar").progressbar({
value: 37
});
});
But nothing happens to the div in the html - it remains empty and unstyled(ie no additional CSS is applied to it).
I have checked that I have jquery-ui included in my application - in particular, I have made certain the jquery-ui css file is included.
However, I am willing to bet the problem has something to do with jquery-ui not working properly in my app, because I was having another issue with it and the tooltip function, which I asked about over here: positioning jQuery tooltip
This is driving me nuts, does anyone have any ideas?
I had the same problem right now.
It seems like the referenced libaries in the example do not work.
The error i get from the "Firefox - Developer Tools - Browser Console" is:
ReferenceError: $ is not defined
(I tested on Firefox 32.0.3 and IE 11)
If you just copy the example html/jquery source from "http://jqueryui.com/progressbar/" to a local file (lets call it: "testJqueryProgressBar.html") and double click it, you will see no progress bar!
Source of "testJqueryProgressBar.html":
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Progressbar - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.1/jquery-ui.js"></script>
<link rel="stylesheet" href="//jqueryui.com/resources/demos/style.css">
<script>
$(function()
{
$( "#progressbar" ).progressbar({ value: 37 });
});
</script>
</head>
<body>
<div id="progressbar"></div>
</body>
</html>
Therefore i checked the links in the header of the example and all reference something.
So the links are valid!
I even tried to reference the jquery libs from another provider, f.e. : https://developers.google.com/speed/libraries/devguide?hl=de#jquery-ui.
Same problem!
Then i went to http://jqueryui.com/download/
Selected Version : 1.11.1 (Stable, for jQuery1.6+)
Selected a different UI theme at the bottom
Downloaded the zip and referenced these unziped jquery sources in my local example testJqueryProgressBar.html and it worked.

Using external plugins in Sencha Touch

I want to use a simple Sencha Touch keypad plugin.
The plugin code can be found over here.
The keypad can be created in an html file under tags as follows:
<script>
Ext.setup({
onReady: function () {
var basic = new Ext.ux.Keypad();
basic.render('keypad');
}
});
</script>
<div id="keypad"/>
Alternatively, it can be used in a Sencha container as follows too:
...
items:[
{
xtype: 'keypad'
}
]
However, I am not able to get it to work the latter way. I'm new to Sencha and I think I'm not placing the files at the right places or not including them properly. I have already included the following in my index.html:
<script type="text/javascript" charset="utf-8" src="js/sencha-touch-1.1.1/sencha-touch.js"></script>
<link rel="stylesheet" type="text/css" href="js/sencha-touch-1.1.1/resources/css/sencha-touch.css">
<script src="js/Keypad.js" type="text/javascript" charset="utf-8"></script>
Can someone let me know what modifications are necessary in which files so that I can use the keypad plugin directly in a container?
in your app.js file you need to set path for the plugin folder in the loader...
put the ux (plugin)folder where your app.js is located...
in app.js set the following
Ext.Loader.setPath('Ext.ux', 'ux');
On the view where you are using the numpad you need to specify a
requires: ['Ext.ux.NumPad' ...] //All plugin related files
Also ensure that the CSS files are in the proper location...
Hope it helps...