I can change values inside a column on Excel export with this code.
var buttonExp = {
exportOptions: {
format: {
body: function (data, column, row){
return column === 4 ?
data.replace( 'test', 'REPLACED' ) :
data;
}
}
}
};
var table = $('#myTable').DataTable({
dom: 'lfBrtip',
buttons: [
$.extend(true, {}, buttonExp, {
extend: 'excelHtml5',
text: 'Export xls All',
exportOptions: {
modifier: {
page: 'current'
}
}
How can i change the Excel export format of a Column from this:
To this:
The only option i could find is changing the export from xlsx to csv.
Exporting in csv gives the desired output.
Related
I wanted to reverse column on export data from DataTables. I look for method to do it and finally ended up with this way:
$(document).ready(function(){
var arrayCol = new Array();
var table = $('#example').DataTable({
dom: 'Bfrtip',
initComplete:function ( ) {
var len = this.api().columns().count();
var array = Array.from(Array(len).keys())
arrayCol = array.reverse();
},
buttons: [
{
extend: 'excelHtml5',
exportOptions: {
columns: ':visible:not(.not-export-col)',
orthogonal: 'export'
}
},
{
extend: 'pdfHtml5',
orientation: 'landscape',
pageSize: 'A4',
exportOptions: {
columns: arrayCol, // this doesn't work
//columns:[5,4,3,2,1,0], //this work
orthogonal: 'export'
}
}
]
});
});
The var arrayCol when debugging has values but when exporting to PDF the PDF doesn't have any columns.
Maybe it doesn't assign to columns or something like that.
I think the simplest way is to reverse each individual row array, as you are exporting the data. You can use exportOptions.rows to do this.
You also need to reverse the headers, which can be done using exportOptions.format.heeader. In this case, you only get access to one header field at a time, so there is a bit more work needed to build a reversed array of header values and then access each index location in that array:
$(document).ready(function() {
var table = $('#example').DataTable( {
dom: 'Bfrtip',
buttons: [
{
extend: 'pdf',
text: 'To PDF',
exportOptions: {
rows: function ( idx, data, node ) {
return data.reverse();
},
format: {
header: function ( data, idx, node ) {
var headers = $('#example').DataTable().table().header();
var reversedHeaders = headers.innerText.split('\t').reverse();
return reversedHeaders[idx];
}
}
}
}
]
} );
} );
References:
export options
row selectors - function
In my datatable I have some columns with data like this: 'XXXX unit'.
When I export it I want to remove the unit part.
What is the rule I should put here?
exportOptions: {
columns: "thead th:not(.noExport)"
}
Thanks
The following function will remove " unit" from the end of every cell in column 2 (offset index 1) in the body of a table:
exportOptions: {
format: {
body: function ( data, row, column, node ) {
return column === 1 ? data.replace( / unit/g, '' ) : data;
}
}
}
This example uses replace() but there are other ways, of course.
In my case, here is how I placed the above option in my buttons section:
buttons: [
$.extend (
true,
{},
{ exportOptions: {
format: {
body: function ( data, row, column, node ) {
return column === 1 ? data.replace( / unit/g, '' ) : data;
}
}
} },
{ extend: 'excel' }
)
]
There is an example here which also shows how to extract the exportOptions into re-usable code, if you want to apply it to multiple buttons.
I have been tasked with formatting some columns in charts using vue-google-charts, a vue.js wrapper for Google Charts and I am not sure that 'NumberFormat()' is even supported in vue-google-charts.
First, if somebody knows if it is or isn't, I would like to know so I don't waste much time pursuing something that isn't possible. But if it is, I sure would love an example of how to do it.
What we are doing is returning our chart data from the database and passing it into this vue.js wrapper. We are creating several charts but there are columns that have commas in them we want to remove.
Please review the existing code. I am trying to implement this using #ready as documented in the docs for vue-google-charts.
vue-google-charts docs -> https://www.npmjs.com/package/vue-google-charts
Here is our existing code with a little framework of the onChartReady method already in place.
<GChart
v-if="chart.data"
id="gchart"
:key="index"
:options="{
pieSliceText: chart.dropDownPie,
allowHtml: true
}"
:type="chart.ChartType"
:data="filtered(chart.data, chart.query, chart.query_type)"
:class="[
{'pieChart': chart.ChartType == 'PieChart'},
{'tableChart': chart.ChartType == 'Table'}
]"
#ready = "onChartReady"
/>
And then ...
<script>
import { GChart } from 'vue-google-charts';
import fuzzy from 'fuzzy';
import 'vue-awesome/icons';
import Icon from 'vue-awesome/components/Icon';
export default {
components: {
GChart,
Icon
},
props: {
},
data() {
return {
charts: window.template_data,
selected: 'null',
selects: [],
chartToSearch: false,
directDownloads: {
'Inactive Phones' : {
'slug' : 'phones_by_status',
'search_by' : 2,
'search' : '/Inactive/'
},
'Active Phones' : {
'slug' : 'phones_by_status',
'search_by' : 2,
'search' : '/Active/'
},
}
}
},
created(){
for (let i in this.charts){
if( !this.charts[i].slug ) continue;
$.post(ajaxurl, {
action: 'insights_' + this.charts[i].slug,
}, (res) => {
console.log(res.data);
if (res.success) {
this.$set(this.charts[i], 'data', res.data);
}
});
}
// console.log(this.charts);
},
methods: {
onChartReady(chart,google) {
let formatter = new.target.visualization.NumberFormat({
pattern: '0'
});
formatter.format(data, 0);
chart.draw(data)
},
toggleChart(chart) {
jQuery.post(ajaxurl, {
'action': 'update_insight_chart_type',
'chartType': chart.ChartType,
'chartSlug': chart.slug
}, (res) => {
chart.ChartType = res.data
})
},
csvHREF(chart) {
return window.location.href + '&rr_download_csv=' + chart.slug + '&rr_download_csv_search_by=' + chart.query_type + '&rr_download_csv_search=' + chart.query.trim()
},
filtered(data, query, column) {
query = query.trim();
if (query){
let localData = JSON.parse(JSON.stringify(data));
let column_Headers = localData.shift();
localData = localData.filter((row)=>{
if( query.endsWith('/') && query.startsWith('/') ){
return new RegExp(query.replace(/\//g, '')).test(String(row[column]));
}
return String(row[column]).toLowerCase().indexOf(query.toLowerCase()) > -1;
});
localData.unshift(column_Headers);
return localData;
}
return data;
},
filterIcon(chart) {
chart.searchVisible = !chart.searchVisible;
chart.query = "";
setTimeout(()=>{
document.querySelector(`#chart-${chart.slug} .insightSearch`).focus();
}, 1);
}
}
}
document.getElementsByClassName('google-visualization-table')
If anybody can help in ANY way, I am all ears.
Thanks!
not familiar with vue or the wrapper,
but in google charts, you can use object notation in your data,
to provide the formatted values.
all chart types will display the formatted values by default.
google's formatters just simply do this for you.
so, in your data, replace your number values with objects,
where v: is the value and f: is the formatted value...
{v: 2000, f: '$2,000.00'}
see following working snippet...
google.charts.load('current', {
packages: ['table']
}).then(function () {
var chartData = [
['col 0', 'col 1'],
['test', {v: 2000, f: '$2,000.00'}],
];
var dataTable = google.visualization.arrayToDataTable(chartData);
var table = new google.visualization.Table(document.getElementById('chart_div'));
table.draw(dataTable);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
I have a JSON file that contains document titles and a URL for each. So far I've been able to render each document into a table created with DataTables. I also rendered each url into the first table row as a test. It was good that they appeared but it's not what I'm going for.
How can I make it so that each document title is linked with its respective URL? I didn't see any info. about it in the DataTables manual or its forum so I thought I'd ask.
If you'd like to see a snippet of the JSON file, please let me know.
JS snippet:
import $ from 'jquery';
import JSONfile from '../../../public/JSONfile.json';
import { basename } from 'path';
import dt from 'datatables.net';
var tableRes = '';
export default class {
constructor() {
this.loadTableData();
}
loadTableData() {
$.noConflict();
let tableRes = JSONfile.d.results.filter(function(val) {
return (val.FileLeafRef.trim().length > 0);
}).map(function(obj) {
return {
// "FileName": obj.FileLeafRef,
// "Path": obj.EncodedAbsUrl, ///// these are the URLs for each document
"Titles": obj.File.Name
}
});
$('#km-table-id').DataTable( {
columns: [
{ "data": " " },
{ "data": "Titles" }, ///// Ideally I want each Title to be linked in the table---i.e. the document names appearing blue
{ "data": " " }
],
data: tableRes,
"pagingType": "full_numbers"
});
} // ------- loadTableData
} // ------- export default class
Update: Thanks to a user on the DataTables forum, I was able to find a solution. Simply put, I had to use columDefs that was detailed under the columns.render section of the docs :
Code snippet:
return {
"Path": obj.EncodedAbsUrl,
"Titles": obj.File.Name
}
});
$('#km-table-id').DataTable( {
columns: [
{ data: "Path" }, // populates rows with each document link
{ data: "Titles" }, // populates rows with docs
{ data: "check" }
],
columnDefs: [ {
targets: 0,
data: "Path",
render: function(data) {
return 'Download';
}
}],
...
Hyperlinking actual document cells:
columnDefs: [
{
data: "Path",
render: function(data, type, row) {
return $('<a>')
.attr({target: "_blank", href: row.Path})
.text(data)
.wrap('<div></div>')
.parent()
.html();
},
targets: [] // Column position
},
...
I use DataTables to present data in a reporting website that I created. I am working on creating a Report Builder where users can select multiple tables and then columns from those tables for a custom report.
What I want to know is whether there's a way to do this with DataTables. I'm able to get the tables names and column names for the custom report, but I've not been able to figure out how to send it to DataTables. I currently use server side processing and send an ajax call using POST to the DataTable.
I know that I can program in a SQL query based on the selected tables and columns, but I cannot seem to figure out how to have the data sent to DataTables.
Here is how I initialize my DataTables:
$(document).ready(function ()
{
// Setup - add a text input to each footer cell
$('#DataTable tfoot th').each(function () //creates the search bar as the footer
{
var title = $(this).text();
$(this).html('<input type="text" placeholder="Search ' + title + '" />');
});
var table = $('#DataTable').DataTable({
"lengthMenu": [[25, 50, 75, 100, 150, -1], [25, 50, 75, 100, 150, 'All']],
"dom": '<"top"Bifpl<"clear">>rt<"bottom"ip<"clear">>',
"buttons": [{
extend: 'collection',
text: 'Export',
buttons: ['export', { extend: 'csv',
text: 'Export All To CSV', //Export all to CSV file
action: function (e, dt, node, config)
{
window.location.href = './ServerSide.php?ExportToCSV=Yes';
}
}, 'csv', 'pdf', { extend: 'excel',
text: 'Export Current Page', //Export to Excel only the current page and highlight the first row as headers
exportOptions: {
modifier: {
page: 'current'
}
},
customize: function (xlsx)
{
var sheet = xlsx.xl.worksheets['sheet1.xml'];
$('row:first c', sheet).attr('s', '7');
}
}]
}
],
"fixedHeader": { //Keeps the header and footer visiable at all times
header: true,
footer: true
},
"select": true, //sets the ability to select rows
"processing": true, //shows the "Processing" when working
"serverSide": true, //sends data to the server for processing
"ajax": { //where the data is sent and processed
"url": "./ServerSide.php",
"type": "POST"
},
stateSave: true, //Saves the current state of the page
columnDefs: [{ visible: false, targets: 0}], //Hides the first column the ID column
initComplete: function () //sets the search
{
var api = this.api();
// Apply the search
api.columns().every(function ()
{
var that = this;
$('input', this.footer()).on('keyup change', function (e)
{
if (that.search() !== this.value & e.keyCode == 13) //you have to hit enter for the search to start
{
that
.search(this.value)
.draw();
}
});
});
}
});
});
$.fn.dataTable.ext.buttons.export =
{
className: 'buttons-alert', //Adds the "Export all to Excel" button
id: 'ExportButton',
text: "Export All To Excel",
action: function (e, dt, node, config)
{
window.location.href = './ServerSide.php?ExportToExcel=Yes';
}
};
Here is what I can currently get to work:
I'm not sure else anyone would need to help me with this, but if I'm missing something let me know and I'll add it.
I need all the data from all selected tables and columns to be in one DataTables table presented on the website. In the image above I'm showing that I've gotten as far as getting the column headers and using aliases for the tables. I'm working through my FilterSort.class.pph file (which is like the ssp.class.php in DataTables) to see if I can get it to present the table.
I figured it out. I was still calling the correct DataTables functions, but I wasn't passing the data to the functions. I ended up having to update my ServerSide.php file and my FilterSort.class.php file. Those are the ones that all of the other reports use to send data from the server to the screen. After some trial and error, I got it to work and didn't need to change anything in the code posted in my question.