i want to create a pdf report using jspdf but i have a problem with the table and image overlay one to the others. Also it happens with the text that i want to insert in the report. how can i resolve it?
this is code where i am creating the report:
imprimir() {
const doc = new jsPDF({
orientation: "portrait",
unit: "px",
format: "A4",
});
const encabezado = [
"Name",
"Calories",
"Fat",
"Carbs",
"Proteins",
"Iron",
];
const titulo = "ORDER DE TRABAJO - TALLERES DE TERCEROS";
doc.text(titulo, doc.internal.pageSize.width * 0.5, 100, {
aling: "right",
});
const arregloDatos = Object(this.desserts).map(function (obj) {
const datos = [
obj.name,
obj.calories,
obj.fat,
obj.carbs,
obj.protein,
obj.iron,
];
return datos;
});
autoTable(doc, {
head: [encabezado],
body: arregloDatos,
});
const logo = require("../assets/Logo_edese_hd(2).png");
var imgLogo = new Image();
imgLogo.src = logo;
doc.addImage(imgLogo, "PNG", 0, 0, 200, 80);
const hoy = new Date();
doc.save(
hoy.getDate() +
hoy.getMonth() +
hoy.getFullYear() +
hoy.getTime() +
".pdf"
);
}
Related
I am using SheetJS community version in combination with the xlsx-js-style package in order to add styles to the cells.
The SheetJS part works fine, I get my Excel file as intended. But when I try to add a style to a cell (following xlsx-js-style documentation), no style is applied. I do not get any errors either.
This is what I tried (the part that doesn't work is //style A1 cell):
//define column order
var headers = ["fullname", "currentcompany", "currentjobtitle", "statusid", "location", "comments", "linkedinurl", "mobilenumber", "email"]
//create worksheet and workbook
var ws = XLSX.utils.json_to_sheet(filteredProfiles, { header: headers, origin: "A4" });
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
//add custom header names
let Heading = [['Name', 'Company', 'Title', 'Status', 'Location', 'Comments', 'Profile', 'Phone', 'Email']];
XLSX.utils.sheet_add_aoa(ws, Heading, { origin: 'A4' });
//set cols/rows width and height
ws['!cols'] = [];
ws['!rows'] = [];
ws['!cols'] = [
{ 'width': 30 }, // width for col A
{ 'width': 30 }, // width for col B
];
ws['!rows'] = [
{ 'hpt': 60 },// height for row 1
{ 'hpt': 20 },]; //height for row 2
//add title in A1
XLSX.utils.sheet_add_aoa(ws, [
["Recent profiles"]
], { origin: "A1" });
//define current date
let today = new Date();
let dd = String(today.getDate()).padStart(2, '0');
let MM = String(today.getMonth() + 1).padStart(2, '0');
let yyyy = today.getFullYear();
//add current date in A2
XLSX.utils.sheet_add_aoa(ws, [
[`${dd}/${MM}/${yyyy}`]
], { origin: "A2" });
//style A1 cell
ws["A1"].s = {
font: {
name: "Calibri",
sz: 24,
bold: true,
color: { rgb: "FFFFAA00" },
},
};
//generate XLSX file and trigger a download
XLSX.writeFile(wb, "data.xlsx");
I found out that I was missing const XLSX = require('sheetjs-style'); before the code I posted. Now it works.
How would like to modify this codepen https://codepen.io/varcharles/pen/qNQpRv
When hovering a red dot the box on right should change is background related on which hotspot is selected. So, four different images related to 4 different hotspots.
const dataField = document.querySelector('.data');
const points = [
{
x: '30px',
y: '50px',
data: 'Targeting Lasers',
},
{
x: '460px',
y: '210px',
data: 'Targeting Lasers'
},
{
x: '250px',
y: '350px',
data: 'Sheild Generators'
},
{
x: '3890px',
y: '550px',
data: 'Sensor Array'
}
];
points.forEach((point) => {
let img = document.createElement('img');
img.style.left = point.x;
img.style.top = point.y;
img.title = point.data;
img.className= 'overlay-image';
img.src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/544303/Target_Logo.svg"
overlay.appendChild(img);
img.data = point.data;
img.addEventListener('mouseenter', handleMouseEnter);
img.addEventListener('mouseleave', handleMouseLeave);
});
function handleMouseEnter(event) {
dataField.innerHTML = event.currentTarget.data;
}
function handleMouseLeave(event) {
dataField.innerHTML = ' ';
}
Can someone please help me? Thank you a lot for your attention
You can just add more data and assign each data object to the images. The following will change the background image when hovering the hotspot.
const overlay = document.querySelector('.image-overlay');
const dataField = document.querySelector('.data');
const points = [
{
x: '320px',
y: '50px',
data: {
title: 'Extended Cockpit',
image: "url('https://dummyimage.com/320x320/ff0000/fff')",
}
},
{
x: '460px',
y: '210px',
data: {
title: 'Targeting Lasers',
image: "url('https://dummyimage.com/320x320/00ff00/fff')",
}
},
{
x: '250px',
y: '350px',
data: {
title: 'Sheild Generators',
image: "url('https://dummyimage.com/320x320/0000ff/fff')",
}
},
{
x: '3890px',
y: '550px',
data: {
title: 'Sensor Array',
image: "url('https://dummyimage.com/320x320/000000/fff')",
}
}
];
points.forEach((point) => {
let img = document.createElement('img');
img.style.left = point.x;
img.style.top = point.y;
img.title = point.data.title;
img.className= 'overlay-image';
img.src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/544303/Target_Logo.svg"
overlay.appendChild(img);
// Sets title and image data attributes
img.data = point.data;
img.addEventListener('mouseenter', handleMouseEnter);
img.addEventListener('mouseleave', handleMouseLeave);
});
function handleMouseEnter(event) {
// Set title and background image based on data set in target
dataField.innerHTML = event.currentTarget.data.title;
dataField.style.backgroundImage = event.currentTarget.data.image;
}
function handleMouseLeave(event) {
// Reset
dataField.innerHTML = ' ';
dataField.style.backgroundImage = 'none';
}
I have one download button and table that store user data in user.component.html file and when user clicks on the download button then it exports all the table's data into an Excel file.
I want to display a loading spinner when the download takes longer than 1.5 seconds to start.
I am using angular 8.
user.component.html file:
<div class ="container">
<button (click)="generateExcel()">
Generate Excel</button>
<table>
-----table related data
<\table>
</div>
user.component.ts file:
generateExcel() {
//Excel Title, Header, Data
const title = 'Car buyers Report';
const header = ["Year", "Month", "User", "Model"]
const data = [
[2007, 1, "jo", "Volkswagen Passat"],
[2007, 1, "mike ", "Toyota Rav4"],
[2007, 1, "david", "Toyota Avensis"],
[2007, 1, "milenda ", "Volkswagen Gol"]
];
//Create workbook and worksheet
let workbook = new Workbook();
let worksheet = workbook.addWorksheet('Car Data');
//Add Row and formatting
let titleRow = worksheet.addRow([title]);
titleRow.font = { name: 'Comic Sans MS', family: 4, size: 16, underline: 'double', bold: true }
worksheet.addRow([]);
let subTitleRow = worksheet.addRow(['Date : ' + this.datePipe.transform(new Date(), 'medium')])
//Add Image
let logo = workbook.addImage({
base64: logoFile.logoBase64,
extension: 'png',
});
worksheet.addImage(logo, 'E1:F3');
worksheet.mergeCells('A1:D2');
//Blank Row
worksheet.addRow([]);
//Add Header Row
let headerRow = worksheet.addRow(header);
// Cell Style : Fill and Border
headerRow.eachCell((cell, number) => {
cell.fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: 'FFFFFF00' },
bgColor: { argb: 'FF0000FF' }
}
cell.border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } }
})
// worksheet.addRows(data);
// Add Data and Conditional Formatting
data.forEach(d => {
let row = worksheet.addRow(d);
let qty = row.getCell(5);
let color = 'FF99FF99';
if (+qty.value < 500) {
color = 'FF9999'
}
qty.fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: color }
};
});
worksheet.getColumn(3).width = 30;
worksheet.getColumn(4).width = 30;
worksheet.addRow([]);
//Footer Row
let footerRow = worksheet.addRow(['This is system generated excel sheet.']);
footerRow.getCell(1).fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: 'FFCCFFE5' }
};
footerRow.getCell(1).border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } }
//Merge Cells
worksheet.mergeCells(`A${footerRow.number}:F${footerRow.number}`);
//Generate Excel File with given name
workbook.xlsx.writeBuffer().then((data) => {
let blob = new Blob([data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
fs.saveAs(blob, 'CarData.xlsx');
})
}
I imagine your writeBuffer call is what takes you the most time.
As writeBuffer is asynchronous, you could use rxjs observables which allow you to have more complex behaviors than a classic async/await.
First convert your promise to an observable :
// here you have a promise
const wBufferPromise = workbook.xlsx.writeBuffer();
// and here you have an observable, hence the $ char in the variable name
const wBufferObservable = from(wBufferPromise );
You can then probably user timeoutWith from RxJS (which i never used so I won't be able to help you here.
Another possible solution would be to call setTimeout(myFunc,1500) where myFunc sets your spinner visibility if needed.
Edit :
Please have a look at Eliseo's comment.
I just started to work with API's and got a little bit confused of how can I transfer the data which I receive to a JavaScript array.
I have this code which receive the data from Binance API and show it in console.
var burl ='https://api.binance.com';
var query ='/api/v3/klines';
query += '?symbol=BTCUSDT&interval=15m&limit=2';
var url = burl + query;
var ourRequest = new XMLHttpRequest();
ourRequest.open('GET',url,true);
ourRequest.onload = function(){
console.log(ourRequest.responseText);
}
ourRequest.send();
I also have a hard-scripted chart from FusionCharts Library.
The source code of a chart is here - FusionChart Candlestick Chart
const dataSource = {
chart: {
caption: "Bitcoin Price",
subcaption: "Q4-2017",
numberprefix: "$",
pyaxisname: "Price (USD)",
showvolumechart: "1",
vnumberprefix: "$",
vyaxisname: "Volume traded",
exportenabled: 1,
theme: loadedTheme || ThemeAliases.light
},
categories: [
{
category: [
{
label: "Jan",
x: "1"
},
{
label: "Feb",
x: "32"
},
{
label: "Mar",
x: "62"
},
{
label:"Apr",
x:"12"
}
]
}
],
dataset: [
{
data: [
{
tooltext:
"<b>Oct 01, 2017</b><br>Open: <b>$openDataValue</b><br>Close: <b>$closeDataValue</b><br>High: <b>$highDataValue</b><br>Low: <b>$lowDataValue</b><br>Volume: <b>$volumeDataValue</b>",
open: 4341.05,
high: 4403.74,
low: 4269.81,
close: 4403.74,
volume: 1208210000,
x: 1
},
FusionCharts.ready(function() {
var myChart = new FusionCharts({
type: "candlestick",
renderAt: "chart-container",
width: "75%",
height: "100%",
dataFormat: "json",
dataSource
}).render();
});
The result ourRequest.responseText is returned as a string, and not as an array. To fix it, simply use the JSON.parsemethod. You also store it in a variable, example :
var burl ='https://api.binance.com';
var query ='/api/v3/klines';
query += '?symbol=BTCUSDT&interval=15m&limit=2';
var url = burl + query;
var ourRequest = new XMLHttpRequest();
ourRequest.open('GET',url,true);
ourRequest.onload = function(){
// Will convert the string to something Javascript can understand
var result = JSON.parse(ourRequest.responseText);
// You can now use it as an array
console.log(result);
}
ourRequest.send();
Does that answer the question?
I am able to use simile timeline with json file using...
tl.loadJSON("/files/trial.js", function(json, url) { eventSource.loadJSON(json, url); });
I would like to connect it json output.
tl.loadJSON("http://mywebsite.com/events/json/", function(json, url) { eventSource.loadJSON(json, url); });
I am also having trouble adding events manually.
I appreciate any help.
This should be a complete working example of adding an event:
// requires: http://simile.mit.edu/timeline/api/timeline-api.js
<div id='tl' style="height:100px; z-index: 1"></div>
<script>
SimileAjax.History.enabled = false;
// Events that will be loaded via loadJSON method
var timeline_data = {
'events' : [
{
'start': new Date(2011, 9, 6),
'end': new Date(2011, 9, 10),
'title': 'Event 1',
'description': ''
}
,
{
'start': new Date(2011, 9, 7),
'end': new Date(2011, 9, 10),
'title': 'Event 2',
'description': ''
}
]
}
// IMPORTANT PART
// Display new event
// Source of information:
// http://markmail.org/message/zfsq3ue3fovhvtuz#query:+page:1+mid:zfsq3ue3fovhvtuz+state:results
function displayEvent() {
// Define your own event, this is static to make things simple
var evt = new Timeline.DefaultEventSource.Event({
'start': new Date(2011, 9, 7),
'end': new Date(2011, 9, 10),
'title': 'added event',
'description': 'added event',
'color': 'yellow'
});
// eventSource1 is defined lower, you should really refactor this code :-)
eventSource1._events.add(evt);
eventSource1._fire("onAddMany", []);
tl.layout();
}
// Timeline and eventSource1
var tl;
var eventSource1;
// Initialize timeline and load data from variable `timeline_data`
window.onload = function() {
var tl_el = document.getElementById("tl");
eventSource1 = new Timeline.DefaultEventSource();
var theme1 = Timeline.ClassicTheme.create();
theme1.event.bubble.height = 220;
theme1.autoWidth = true; // Set the Timeline's "width" automatically.
// Set autoWidth on the Timeline's first band's theme,
// will affect all bands.
theme1.timeline_start = new Date(Date.UTC(1924, 0, 1));
theme1.timeline_stop = new Date(Date.UTC(2160, 0, 1));
var d = Timeline.DateTime.parseGregorianDateTime("1900")
var bandInfos = [
Timeline.createBandInfo({
width: "80%",
intervalUnit: Timeline.DateTime.WEEK,
intervalPixels: 200,
eventSource: eventSource1
// theme: theme
}),
Timeline.createBandInfo({
width: "20%",
intervalUnit: Timeline.DateTime.MONTH,
intervalPixels: 200,
eventSource: eventSource1,
overview: true
// theme: theme
})
];
bandInfos[1].syncWith = 0;
bandInfos[1].highlight = true;
// create the Timeline
tl = Timeline.create(tl_el, bandInfos, Timeline.HORIZONTAL);
var url = '.'; // The base url for image, icon and background image
// references in the data
eventSource1.loadJSON(timeline_data, url); // The data was stored into the
// timeline_data variable.
tl.layout(); // display the Timeline
};
// Resizing from distribution example
var resizeTimerID = null;
function onResize() {
if (resizeTimerID == null) {
resizeTimerID = window.setTimeout(function() {
resizeTimerID = null;
tl.layout();
}, 500);
}
}
</script>