How to download collapsible table with accordion in MUI table in PDF format using JSPDF and JSPDF Autotable library - jspdf

I am trying to download MUI table in React using JSPDF and JSPDF Autotable library ,but the rows inside the accordion is getting downloaded in single row.
How can I download the inner rows in the table in PDF format?
My code is as below:
import React, { Component } from 'react';
import { jsPDF } from "jspdf";
import 'jspdf-autotable';
import './DownloadPdf.scss';
class DownloadPdf extends Component {
pdfGenerate=(props)=>{
const unit = "px";
const size = "A4"; // Use A1, A2, A3 or A4
const orientation = "portrait"; // portrait or landscape
const doc = new jsPDF (orientation, unit, size);
doc.text(30, 80, "Amortization Schedule")
doc.autoTable({
html: "#amortization-table",
includeHiddenHtml: true
headStyles: {
fontStyle: "normal",
font: "Helvetica",
fillColor: "#333",
textColor: "#fff",
fontSize: 12,
},
startY: 100,
columnStyles: {0: {cellWidth: 'auto', minCellHeight: 20},1: {cellWidth: 'auto'},2: {cellWidth: 'auto'},3: {cellWidth: 'auto'},4: {cellWidth: 'auto'}},
showHead: "everyPage",
didDrawPage: function (data) {
// Header
doc.addImage(img, 'png', 10, 10, 150, 45)
// Footer
var str = "Page " + doc.internal.getNumberOfPages();
doc.setFontSize(10);
// jsPDF 1.4+ uses getWidth, <1.4 uses .width
var pageSize = doc.internal.pageSize;
var pageHeight = pageSize.height
? pageSize.height
: pageSize.getHeight();
doc.text(str, data.settings.margin.left, pageHeight - 10);
}
})
doc.save('test.pdf')
}
render() {
return (
<div className="pdf-container">
<span className="pdf-icon"></span>
<a onClick = {this.pdfGenerate}>Download PDF</a>
</div>
);
}
}
export default DownloadPdf;
///
I am trying to use the
Sample Collapsible Table

Related

Highcharts react X-range: how to add a custom component?

I have an x-range chart, and I need to add custom components (SVG icons) at the start of each data point ("x" prop value). Something like this (red circles are where custom components should be):
My idea is to place a custom component with position absolute, but I can't figure out how to transform timestamp values of the X axis to pixels. Or maybe there is a better solution?
Codesandbox demo
There are multiple ways to achieve what you want:
A. You can get a chart reference and use Axis.toPixels method to calculate the required coordinates:
export default function Chart() {
const chartComponentRef = useRef(null);
const [x1, setX1] = useState(0);
useEffect(() => {
if (chartComponentRef) {
const chart = chartComponentRef.current.chart;
const xAxis = chart?.xAxis[0];
const x1 = xAxis?.toPixels(Date.UTC(2022, 7, 10));
setX1(x1);
}
}, [chartComponentRef]);
return (
<div style={{ position: "relative" }}>
<HighchartsReact
ref={chartComponentRef}
highcharts={Highcharts}
options={staticOptions}
/>
<div style={{ position: "absolute", bottom: 70, left: x1 }}>ICON</div>
</div>
);
}
Live demo: https://codesandbox.io/s/highcharts-react-custom-componentt-ysjfh8?file=/src/Chart.js
API Reference: https://api.highcharts.com/class-reference/Highcharts.Axis#toPixels
B. You can also get coordinates from a point:
useEffect(() => {
if (chartComponentRef) {
const chart = chartComponentRef.current.chart;
const point = chart.series[0].points[2];
setX1(chart.plotLeft + point.plotX);
}
}, [chartComponentRef]);
Live demo: https://codesandbox.io/s/highcharts-react-custom-componentt-f7nveg?file=/src/Chart.js
C. Use Highcharts API to render and update the custom icons:
const staticOptions = {
chart: {
type: "xrange",
height: 200,
events: {
render: function () {
const chart = this;
const r = 10;
const distance = 25;
chart.series[0].points.forEach((point, index) => {
if (!point.customIcon) {
point.customIcon = chart.renderer
.circle()
.attr({
fill: "transparent",
stroke: "red",
"stroke-width": 2
})
.add();
}
point.customIcon.attr({
x: point.plotX + chart.plotLeft + r,
y:
point.plotY +
chart.plotTop +
(index % 2 ? distance : -distance),
r
});
});
}
}
},
...
};
Live demo: https://codesandbox.io/s/highcharts-react-custom-componentt-f-87eof0?file=/src/Chart.js
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#circle

How to add a horizontal bottom line in google column chart

As shown in this image link above. Can any body please tell me how can I add this bold horizontal line below google column chart where Sales Date and Narration are written in the image above.
Following is my draw chart function.
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Sales Date');
data.addColumn('number', 'Anomaly');
data.addColumn('number', 'NIV');
data.addColumn('number', 'GIV');
for (var i = 0; i < graphData.length; i++) {
data.addRow([graphData[i].date, graphData[i].anomaly, graphData[i].NIV, graphData[i].GIV]);
}
// Set chart options
var options = {
'title': 'Details of anomaly',
'width': 700,
'height': 300,
'isStacked': true,
'fontSize': 10,
'legend': { position: 'bottom', maxLines: 1 },
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}

Trouble with jspdf script

I have added this jspdf script on my website to download pdf. However I get this error.
Uncaught TypeError: Cannot read property '1' of undefined
at f.renderParagraph (jspdf.min.js:202)
at f.setBlockBoundary (jspdf.min.js:202)
at k (jspdf.min.js:202)
at k (jspdf.min.js:202)
at k (jspdf.min.js:202)
at jspdf.min.js:202
at l (jspdf.min.js:202)
at Image.i.onerror.i.onload (jspdf.min.js:202)
This happens on certain pages while others work fine.I have added the code I am using below. I am not sure if it is anything to do with my code or the jspdf.
//Code I am using:
<script type="text/javascript">
function HTMLtoPDF(){
var pdf = new jsPDF('p', 'pt', 'letter');
source = $('#HTMLtoPDF')[0];
specialElementHandlers = {
'#bypassme': function(element, renderer){
return true
}
}
margins = {
top: 50,
left: 60,
right:60,
width: 545
};
pdf.fromHTML(
source // HTML string or DOM elem ref.
, margins.left // x coord
, margins.top // y coord
, {
'width': margins.width // max width of content on PDF
, 'elementHandlers': specialElementHandlers
},
function (dispose) {
// dispose: object with X, Y of the last line add to the PDF
// this allow the insertion of new lines after html
pdf.save('Download.pdf');
}
)
}
</script>
<button type="button" onclick="HTMLtoPDF()" style=" height: 40px; width: 154px; background-color: #008800; color: #ffffff; font-size: 150%;">Download PDF </button>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"> </script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.min.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var str_pdf = $("#HTMLtoPDF").html();
var regex = /<br\s*[\/]?>/gi;
$("#HTMLtoPDF").html(str_pdf.replace(regex, '<p data-empty="true"><br></p>'));
});
function HTMLtoPDF(){
var pdf = new jsPDF('p', 'pt', 'a4');
source = $('#HTMLtoPDF')[0];
specialElementHandlers = {
'#bypassme': function (element, renderer) {
return true
}
};
margins = {
top: 30,
bottom: 30,
left: 40,
width: 522
};
pdf.fromHTML(
source,
margins.left,
margins.top, {
'width': margins.width,
'elementHandlers': specialElementHandlers
},
function (dispose) {
pdf.save('Download.pdf');
}, margins);
}
</script>
<!-- these js files are used for making PDF -->

Format content after table (jsPDF autotable)

i want to add content after a table in a pdf file that was created with jsPDF autotable.
My Code:
$('#printBtn').on('click', function() {
var pdf = new jsPDF('p', 'pt', 'a4');
var res = pdf.autoTableHtmlToJson(document.getElementById("tablePrint"));
var anfang = "Anfang";
pdf.text(anfang, 14, 30);
pdf.autoTable(res.columns, res.data, {
theme : 'plain',
styles: {
fontSize: 12
},
showHeader: 'never',
createdCell: function(cell, data) {
var tdElement = cell.raw;
if (tdElement.classList.contains('hrow')) {
cell.styles.fontStyle = 'bold';
}
}
});
var ende = $('#ende_text').text();
pdf.text(ende, 0, 12);
pdf.save("test.pdf");
});
My Problem is that the code isn't formatted. The tags and everything else was ignored by jsPDF.
How can i fix that or what can i do that the text has line breaks and not overflow?
Thanks for help!
margins={
top=50,
left=30,
bottom=50,
width=520
}
var pdf = new jsPDF("p", "pt","a4");
var res = pdf.autoTableHtmlToJson(document.getElementById("table2"));
pdf.autoTable(res.columns, res.data,{
margin: { left: 30,bottom:100},
startY: 30, pageBreak: 'always',
styles: {overflow: 'linebreak', columnWidth: 'wrap', font: 'arial',
cellPadding: 8, overflowColumns: 'linebreak'}
});
pdf.fromHTML($("#editor1").get(0), 30, pdf.autoTableEndPosY() + 20, {
'width': margins.width
},function(dispose)
{
var iframe = document.createElement('iframe');
iframe.setAttribute('style','position:absolute;right:0; top:0; bottom:0; height:100%; width:40%; padding:20px;');
document.body.appendChild(iframe);
iframe.src = pdf.output('datauristring');
//pdf.save('name.pdf');
},
margins);
iam using the latest version of jspdf.min.js and jspdf.autotable.js
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/2.3.5/jspdf.plugin.autotable.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.4.1/jspdf.min.js"></script>

react-native - this.porps.inGrid is not a function

I'm trying to display a nested array containing numbers. The array has 6 elements (arrays). Each nested array contains 6 further elements/numbers. I'm trying to display each number in a Square component. I've got an error: this.props.inGrid.foreach is not a function.
import React, { Component, PropTypes } from 'react';
import { View, StyleSheet } from 'react-native';
import Square from './Square';
import * as globalStyles from '../styles/global';
export default class Grid extends Component {
render() {
const row = [];
this.props.inGrid.foreach((r, i) => {
row.push(
<Square key={i} sqValue={r[i]} />
);
});
return (
<View style={styles.grid}>
{row}
</View>
);
}
}
Grid.propTypes = {
numbers: PropTypes.object
};
const styles = StyleSheet.create({
grid: {
backgroundColor: globalStyles.BG_COLOR,
flexDirection: 'row',
padding: 20,
justifyContent: 'center'
}
});
Below is the Square component:
import React, { PropTypes } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import * as globalStyles from '../styles/global';
const Square = ({ sqValue }) => {
return (
<View style={styles.square}>
<Text>{sqValue}</Text>
</View>
);
};
Square.propTypes = {
sqValue: PropTypes.number
};
const styles = StyleSheet.create({
square: {
backgroundColor: globalStyles.BAR_COLOR,
width: 50,
height: 50,
borderWidth: 1,
borderStyle: 'solid',
borderColor: 'red'
}
});
export default Square;
What am I doing wrong?
It appears that you're calling:
this.props.inGrid.foreach
but the function is actually called forEach

Resources