Angular: HTML Table export to csv file - html

I'm trying to export a painted html table completely dynamically into a csv file. I tried to implement several Scripts, functions.etc but I have not obtained the desired result. If anyone can help me, I'd be very grateful.
The information in the table is loading from a Request in "jsonData", It is important to clarify that I do not require to know the "Headers", only the information inside the table body:
ts Code:
jsonData:any;
_object = Object;
"jsonData" looks like:
[{
Subject_ID: "ACCT101",
First_Available_Date: "01/01/01",
....
},
{
Subject_ID: "510862185-X",
First_Available_Date: "06/04/19"..}....
]
HTML
<table>
<thead>
<tr>
<th *ngFor="let header of _object.keys(jsonData[0]); let i = index">{{header}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of jsonData; let i = index">
<td *ngFor="let objKey of _object.keys(row); let j = index">{{ row[objKey] }} </td>
</tr>
</tbody>
</table>
<button class="btn btn-submit btn-sm float-right" type="submit" (click)="export()">
Submit
</button>

Please try below code. this will extract data from table and download as csv.
<!DOCTYPE html>
<html>
<head>
<style>
td, table,th{
border: solid 1px black;
}
</style>
</head>
<body>
<table id="data_table">
<thead>
<tr>
<th>Subject_ID</th>
<th>First_Available_Date</th>
</tr>
</thead>
<tbody>
<tr>
<td>ACCT101</td>
<td>01/01/01</td>
</tr>
<tr>
<td>510862185-X</td>
<td>06/04/19</td>
</tr>
<tr>
<td>New data</td>
<td>New data 1</td>
</tr>
</tbody>
</table>
<script>
function exportit() {
var csv='';
table=document.getElementById("data_table");
tr=table.children[0].children[0];
for(i=0;i<tr.children.length;i++)
{
csv+=tr.children[i].innerText+",";
}
csv=csv.substring(0,csv.length-1)+"\n";
tbody=table.children[1];
for(i=0;i<tbody.children.length;i++)
{
for(j=0;j<tbody.children[i].children.length;j++)
{
csv+=tbody.children[i].children[j].innerText+",";
}
csv=csv.substring(0,csv.length-1)+"\n";
}
csv=csv.substring(0,csv.length-1)+"\n";
var hiddenElement = document.createElement('a');
hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv);
hiddenElement.target = '_blank';
hiddenElement.download = 'data.csv';
hiddenElement.click();
}
</script><br>
<button onclick="exportit()">export</button>
</body>
</html>

Related

Auto increment column number in html table boostrap 5?

I am trying to auto increment column with header ID, using reactjs bootstrap5.
The table loads data from a database.
<table className="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Tick</th>
<th>Percent</th>
<th>Ratio</th>
<th>Broke</th>
<th />
</tr>
</thead>
<tbody>
{ this.props.sett_list.map(dca_sett_list_item => (
<tr key={sett_list_item.id}>
<td>{sett_list_item.id}</td>
<td>{sett_list_item.ticker}</td>
<td>{sett_list_item.percent_down}</td>
<td>{sett_list_item.pe_ratio}</td>
<td><button className='btn btn-primary btn-sm'>BROKE</button></td>
<td><button onClick={this.props.deleteSettings_T.bind(this, sett_list_item.id)}className='btn btn-danger btn-sm'>Delete</button></td>
</tr>
)) }
</tbody>
</table>
I found an answer which directs towards using css:
table {
counter-reset: tableCount;
}
.counterCell:before {
content: counter(tableCount);
counter-increment: tableCount;
}
Do I make a custom.css and add the above code to get the functionality? Or is there a better way to do this in bootstrap 5?

Use for loop to display array in HTML tables without duplicating

I am trying to write a simple product management program. Basically, when users input a product name, it will be saved to an array and displayed on the table using a for loop.
I am having trouble with my codes here. It shows duplicate each time I click add a product. For example, the 1st time I add productA, it shows productA. The second time I add productB, it shows productA, productA, productB (duplicate productA).
I know the problem is within the loop I use, but have no idea how to fix.
I cannot paste HTML code here, but here is the link to my codes. https://github.com/minhle0105/functionPractice/tree/main/productManagement
Thanks everyone
You were displaying products array instead of the new product, that's what it was displaying the whole array.
TRY This
<!DOCTYPE html>
<html>
<head>
<title>Product List Management</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<p>Add New Product</p>
<div class="add_product">
<input type="text" name="productAdd" id="productAdd" placeholder="New Product">
<button type="button" id="addbtn" onclick="addProductToList()">Add</button>
</div>
<p>Display All Products</p>
<div class="productDisplay" id="productDisplay">
<table class="table">
<thead>
<tr>
<th style="text-align: left; background-color: white;">Product Names</th>
</tr>
</thead>
<tbody id="result">
</tbody>
</table>
</div>
<script>
let products = [];
let count = 0;
function addProductToList() {
let productAdd = document.getElementById("productAdd").value;
products.push(productAdd);
document.getElementById("result").innerHTML ="";
displayProduct(products)
}
function displayProduct(products) {
for(let i=0; i<products.length; i++){
document.getElementById("result").innerHTML +=`<tr>
<td>${i+1}</td>
<td>${products[i]}</td>
<td><button type="button" class="btn edit">Edit</button></td>
<td><button type="button" class="btn delete">Delete</button></td>
</tr>
`
}
}
</script>
</body>
</html>
Something like this
let products = [];
let count = 0;
function addProductToList() {
let productAdd = document.getElementById("productAdd").value;
products.push(productAdd);
document.getElementById("productAdd").value=''; document.getElementById("result").innerHTML ="";
displayProduct(products)
}
function displayProduct(products) {
for (var i = 0; i < products.length; i++) {
document.getElementById("result").innerHTML +=`<tr>
<td>${products[i]}</td>
</tr>
`
}
}
<div class="add_product">
<input type="text" name="productAdd" id="productAdd" placeholder="New Product" required>
<button type="button" id="addbtn" onclick="addProductToList()">Add</button>
</div>
<div class="productDisplay" id="productDisplay" style="margin-top: 15px;">
<table class="table">
<thead>
<tr>
<th>Product</th>
</tr>
</thead>
<tbody id="result">
</tbody>
</table>
</div>

jquery - Replace an element from the cloned html

I want to achieve the below two scenarios:
Need to add rows on click of the plus button.
Need to replace the plus button with a hyperlink from the dynamically added rows.
<button type="button" class="addRow" />+</button>
Replace the above button with the below for all the dynamically added rows.
Remove
I've done the first scenario and stuck with the second one.
HTML:
<table id="exampleTbl">
<tr>
<td>1</td>
<td>2</td>
<td>
<button type="button" class="addRow" />+</button>
</td>
</tr>
<tr>
<td>3</td>
<td>4</td>
<td>
<button type="button" class="addRow" />+</button>
</td>
</tr>
</table>
jQuery:
$(function() {
$('#exampleTbl').delegate('button.addRow', 'click', function() {
var row = $(this).closest('tr'); // get the parent row of the clicked button
var html = $(this).closest('tr').clone();
$(html).insertAfter(row); // insert content
});
});
You could try this.
$(function() {
$('#exampleTbl').delegate('button.addRow', 'click', function() {
var row = $(this).closest('tr'); // get the parent row of the clicked button
var html = $(this).closest('tr').clone();
$(html).insertAfter(row); // insert content
let btn = $('Remove');
btn.click(function () {
$(html).remove(); // Remove row on click
})
$(html).find('.addRow').replaceWith(btn);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="exampleTbl">
<tr>
<td>1</td>
<td>2</td>
<td>
<button type="button" class="addRow">+</button>
</td>
</tr>
<tr>
<td>3</td>
<td>4</td>
<td>
<button type="button" class="addRow">+</button>
</td>
</tr>
</table>
Working JSFiddle: https://jsfiddle.net/j18yfwLv/1/
Note: I just replaced the button with the content you wanted, do you want the button to remove the row as well?

Print preview is not displaying the right layout

I need to print my html so I lay out the way I want the print out to be. But when I click on the print button and get directed to the print preview, the layout are all messed up. Please see my code below:
in html
<div id="print-section" *ngIf="propertyLedger">
<h2>SOSA | PMIS</h2>
<hr>
<table class="table borderless">
<tr>
<th class="col-md-2">Transaction Date</th>
<td>{{dateToday | date}}</td>
</tr>
<tr>
<th class="col-md-2">Collecting Agent</th>
<td>{{propertyLedger.CollectinAgentName}}</td>
</tr>
<tr>
<th class="col-md-2">Unit Name</th>
<td>{{propertyLedger.UnitName}}</td>
</tr>
<tr>
<th class="col-md-2">Payment Type</th>
<td>{{propertyLedger.PaymentType}}</td>
</tr>
<tr>
<th class="col-md-2">O.R. Number</th>
<td>{{propertyLedger.ORNumber}}</td>
</tr>
<tr>
<th class="col-md-2">Remarks</th>
<td>{{propertyLedger.Remarks}}</td>
</tr>
</table>
<hr>
<h3>Details</h3>
<hr>
</div>
<button
class="btn btn-primary" (click)="print()">Print</button>
in the ts file
print() {
let printContents, popupWin;
printContents = document.getElementById('print-section').innerHTML;
popupWin = window.open('', '_blank', 'top=0,left=0,height=100%,width=auto');
popupWin.document.open();
popupWin.document.write(`
<html>
<head>
<title>Print tab</title>
<style>
//........Customized style.......
</style>
</head>
<body onload="window.print();window.close()">${printContents}</body>
</html>`
);
popupWin.document.close();
}
in my layout
as soon as I click the print =>
in my print preview
It seems that the texts in the left part of the table goes to the center. Can you help me with this please. If you have a way to get my desired layout without any table that will be best! Thank you so much.
Just read up. A default in HTML has these properties.
th {
display: table-cell;
vertical-align: inherit;
font-weight: bold;
text-align: center
}
You have to change it to something like this:
th {
display: table-cell;
vertical-align: inherit;
font-weight: bold;
text-align: left;
}
Moreover, if you are not using HTML5 you can also make the tag something like this:
<th align="left" class="col-md-2">Unit Name</th>

How to update data copy in next table using angular js

Hi i m using in my project a simple functionality.
i have a table and some data is fetch data in json file .
Data is coming and if i click to name than edit mode is on if i blur than hide the edit mode and show the view mode is fine i have do this .
now i have a update button if i click to this button than only updated data in insert next row how to do this please check to this and help me .
My code is this
var myApp = angular.module('myApp', []);
myApp.controller('myCntrl', function($scope, $http){
$http.get('js/list.json').success(function(data){
$scope.emplyeList = data;
});
$scope.updateSec= function(employe){
alert("Rohit");
}
});
.click{
cursor: pointer;
text-decoration: underline;
}
.normal-table{
width: 50%;
border-collapse: collapse;
}
.normal-table th{
border: solid 2px rgba(0,0,0,0.1);
}
.normal-table td{
border: solid 2px rgba(0,0,0,0.1);
text-align: center;
padding: 10px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCntrl">
<body>
<table class="normal-table">
<thead>
<tr>
<th>Name</th>
<th>ID</th>
<th>Address</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="employe in emplyeList">
<td>
<div ng-show="!data" ng-click="data=true" class="click">{{employe.name}}</div>
<div ng-show="data"><input ng-blur="data=false" type="text" ng-model="employe.name" /></div>
</td>
<td>
<div ng-show="!data">{{employe.ID}}</div>
<div ng-show="data"><input type="text" ng-model="employe.ID" /></div>
</td>
<td>
<div ng-show="!data">{{employe.add}}</div>
<div ng-show="data"><input type="text" ng-model="employe.add" /></div>
</td>
</tr>
<tr>
<td colspan="3">
<button ng-click="updateSec(employe)">Update</button>
</td>
</tr>
</tbody>
<tbody>
<tr ng-repeat="updatEm in employe">
<td>{{updatEm.name}}</td>
<td>{{updatEm.ID}}</td>
<td>{{updatEm.add}}</td>
</tr>
</tbody>
</table>
</div>
My Json file is
[
{"name":"Rohit", "ID":"5Rt", "add":"Delhi"},
{"name":"Kiran", "ID":"4Kn", "add":"UP"},
{"name":"Abhay", "ID":"3Ay", "add":"HR"},
{"name":"Rahul", "ID":"2Rl", "add":"UK"}
]
HTML
<tr ng-repeat="employe in emplyeList" ng-click="updateSec(employe)">
</tr>
<tr>
<td colspan="3">
<button ng-click="showData()">Update</button>
</td>
</tr>
<tr ng-if="showEmployee" ng-repeat="employe in modifiedEmplyee">
<td>{{employe.name}}</td>
<td>{{employe.ID}}</td>
<td>{{employe.add}}</td>
</tr>
Script
//Display list
$scope.showEmployee = false;
//Create an array to hold updated employee
$scope.modifiedEmplyee = [];
//Set updated field to identify updated employee
$scope.updateSec = function (employe) {
employe.updated = true;
$scope.showEmployee = false;
}
//Show data and copy modilfied list
$scope.showData = function () {
$scope.showEmployee = true;
$scope.modifiedEmplyee = [];
for(var i = 0; i< $scope.emplyeList.length; i++)
{
var emp = $scope.emplyeList[i];
if(emp.updated && emp.updated == true){
$scope.modifiedEmplyee.push(emp);
}
}
}
DEMO