Сгенерировать таблицу в XLSX файл
Есть таблица, нужно скачать ее как excel файл. Подключил table2excel - все отлично. Попросили использовать SheetJS. С помощью SheetJS скачиваю таблицу, но в скачаном файле всего одна строка. Как вывести всю таблицу?
Вот таблица :
<div class="table-responsive project-list-view" id="projects-list">
<table class="table table-hover" id="projectsTable" style="overflow: auto">
<thead>
<tr>
<th ng-if="columnVisibility.id" class="id" sortable-heading sort="sort" by="id" style="width: 2%">ID</th>
<th ng-if="columnVisibility.name" class="name" sortable-heading sort="sort" by="name" style="width: 6%">
{{'projects.labels.name' | translate }}
</th>
<th ng-if="!showView && columnVisibility.company_name" class="company_name" sortable-heading sort="sort"
by="company_name" style="width: 8%">
{{'projects.labels.company_name' | translate }}
</th>
<th ng-if="columnVisibility.city" class="city" sortable-heading sort="sort" by="city" style="width: 6%">
{{'projects.labels.city' | translate }}
</th>
<th ng-if="columnVisibility.country" class="country" sortable-heading sort="sort" by="country" style="width: 6%">
{{'projects.labels.country' | translate }}
</th>
<th ng-if="columnVisibility.start_date" class="start_date" sortable-heading sort="sort" by="start_date" style="width: 8%">
{{'projects.labels.start_date' | translate }}
</th>
<th ng-if="columnVisibility.rate_hourly_yearly" class="rate_hourly_yearly" sortable-heading="sort" by="rate_hourly/yearly" style="width: 8%">
{{'projects.labels.rate_hourly/yearly' | translate}}
</th>
<th ng-if="columnVisibility.employment_type" class="employment_type" style="width: 4%">
{{'projects.labels.employment_type' | translate }}
</th>
<th ng-if="columnVisibility.user_name" class="user_name" sortable-heading sort="sort" by="user_name" style="width: 8%">
{{'projects.labels.user_name' | translate }}
</th>
<th ng-if="columnVisibility.created_at" class="created_at" sortable-heading sort="sort" by="created_at" style="width: 5%">
{{'projects.labels.created_at' | translate }}
</th>
<th ng-if="columnVisibility.status_changed_stop" class="status_changed_stop" sortable-heading sort="sort" by="project_status_changed_at" style="width: 5%">
{{'projects.labels.project_status_changed_at' | translate }}<br>
/{{'projects.labels.project_status_stop' | translate }}
</th>
<th ng-if="columnVisibility.status" class="status" sortable-heading sort="sort" by="status" style="width: 5%">
{{'projects.labels.status' | translate }}
</th>
<th ng-if="columnVisibility.candidates_count" class="candidates_count" sortable-heading sort="sort" by="candidates_count" style="width: 4%">
{{'projects.labels.candidates_count' | translate }}
</th>
<th ng-if="columnVisibility.days_elapsed" class="days_elapsed" sortable-heading sort="sort" by="days_elapsed" style="width: 4%">
{{'projects.labels.days_elapsed' | translate }}
</th>
<th ng-if="columnVisibility.days_remaining" class="days_remaining" sortable-heading sort="sort" by="days_remaining" style="width: 4%">
{{'projects.labels.days_remaining' | translate }}
</th>
<th ng-if="columnVisibility.extended_projects_list && canViewExtendedProjectsList(project.concerns_current_user)" class="extended_projects_list" sortable-heading sort="sort" by="extended_projects_list">
{{'extended_projects_list' | translate }}
</th>
<th style="width: 5%">{{'projects.labels.actions' | translate }}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="project in projects">
<td ng-if="columnVisibility.id" class="id">
<i ng-if="::project.invalid" class="fa fa-exclamation-circle" aria-hidden="true"></i>
{{ ::project.id }}
</td>
<td ng-if="columnVisibility.name" class="name">
<a ui-sref='projects.show({id: project.id})' href="#">{{::project.name }}</a>
</td>
<td ng-if="!showView && columnVisibility.company_name" class="company_name">
<a ui-sref='clients.show({id: project.client_id})' href="#">
{{ ::project.client_name}}
</a>
</td>
<td ng-if="columnVisibility.city" class="city">{{ ::project.address.city }}</td>
<td ng-if="columnVisibility.country" class="country">{{ 'countries.' + project.address.country | translate }}</td>
<td ng-if="columnVisibility.start_date" class="start_date">{{ ::project.start_date | date }}</td>
<td ng-if="columnVisibility.rate_hourly_yearly" class="rate_hourly_yearly">
{{project.hourly_rate == null ? "" : project.hourly_rate}}
{{project.hourly_currency == null ? "-" : project.hourly_currency}} /
{{project.annual_rate == null ? "" : project.annual_rate}}
{{project.annual_currency == null ? "-" : project.annual_currency}}
</td>
<td ng-if="columnVisibility.employment_type" class="employment_type">
<div ng-repeat="employment_type in ::project.employment_types ">
<span>{{ 'abr_' + employment_type.name | translate }}</span>
</div>
</td>
<td ng-if="columnVisibility.user_name" tabindex="1" class="user_name">
<div class="btn-group max" uib-dropdown>
<button id="single-button" type="button" class="btn btn-default" uib-dropdown-toggle>
{{ ::project.supervisors[0].name }} <span class="caret"></span>
</button>
<ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="single-button">
<li ng-repeat="supervisor in project.supervisors" role="menuitem" class="text-center">
<a> {{::supervisor.name}} <br>
<small>({{ ::supervisor.email }})</small>
</a>
</li>
</ul>
</div>
</td>
<td ng-if="columnVisibility.created_at" class="created_at">{{ ::project.created_at | date }}</td>
<td ng-if="columnVisibility.status_changed_stop" class="status_changed_stop">{{(project.status != 'open' ? (project.project_status_changed_at | date) : "‐") }}</td>
<td ng-if="columnVisibility.status" class="status">
<div ng-switch="project.status">
<span change-project-status-modal project="project" index="$index" data="projects"
ng-switch-when="closed" class="label label-default"
can-edit="canEdit(project.concerns_current_user)"
ng-class="{pointer: canEdit(project.concerns_current_user) }">
{{::project.status | translate }}
</span>
<span change-project-status-modal project="project" index="$index" data="projects"
ng-switch-when="on-hold" class="label label-warning"
can-edit="canEdit(project.concerns_current_user)"
ng-class="{pointer: canEdit(project.concerns_current_user)}">
{{::project.status | translate }}
</span>
<span change-project-status-modal project="project" index="$index" data="projects"
ng-switch-when="open" class="label label-success"
can-edit="canEdit(project.concerns_current_user)"
ng-class="{pointer: canEdit(project.concerns_current_user)}">
{{::project.status | translate }}
</span>
<span change-project-status-modal project="project" index="$index" data="projects"
ng-switch-when="in-progress" class="label label-success"
can-edit="canEdit(project.concerns_current_user)"
ng-class="{pointer: canEdit(project.concerns_current_user) }">
{{::project.status | translate }}
</span>
<span change-project-status-modal project="project" index="$index" data="projects"
ng-switch-when="to-do" class="label label-default"
can-edit="canEdit(project.concerns_current_user)"
ng-class="{pointer: canEdit(project.concerns_current_user) }">
{{::project.status | translate }}
</span>
<span change-project-status-modal project="project" index="$index" data="projects"
ng-switch-when="sent-to-client" class="label label-default"
can-edit="canEdit(project.concerns_current_user)"
ng-class="{pointer: canEdit(project.concerns_current_user) }">
{{::project.status | translate }}
</span>
<span change-project-status-modal project="project" index="$index" data="projects"
ng-switch-when="standing-order" class="label label-default"
can-edit="canEdit(project.concerns_current_user)"
ng-class="{pointer: canEdit(project.concerns_current_user) }">
{{::project.status | translate }}
</span>
</div>
</td>
<td ng-if="columnVisibility.candidates_count" class="candidates_count" style="width: 4%">
<a ui-sref="projects.show({id: project.id, tab: 'candidates'})" type="button"
class="btn btn-default project-count">
{{::project.candidates_count}}
</a>
</td>
<td ng-if="columnVisibility.days_elapsed" class="days_elapsed">
<span ng-if="project.status =='open'">
<timer language="pl" max-time-unit="'day'" start-time="now - project.elapsed_time">
{{days}} dni, {{hhours}}:{{mminutes}}h
</timer>
</span>
<span ng-if="project.status !=='open'">
<static-time elapsed="true" time-stamp="project.elapsed_time"></static-time>
</span>
</td>
<td ng-if="columnVisibility.days_remaining" class="days_remaining">
<span ng-if="project.status =='open'">
<span ng-class="{overdue: isNegative}">
<span ng-if="isNegative">-</span>
<timer language="pl" max-time-unit="'day'" allow-negative="true" is-negative="isNegative"
end-time="project.remaining_time + now">
{{days}} dni, {{hhours}}:{{mminutes}}h
</timer>
</span>
</span>
<span ng-if="project.status !=='open'">
<static-time time-stamp="project.remaining_time"></static-time>
</span>
</td>
<td ng-if="columnVisibility.extended_projects_list && canViewExtendedProjectsList(project.concerns_current_user)" class="extended_projects_list">
<table class="candidate-list-view" style="width: 100%; min-width: 350px">
<thead>
<tr>
<th class="pointer">
{{'candidates.forename' | translate }}
</th>
<th class="pointer">
{{'candidates.rate_hourly/yearly' | translate }}
</th>
<th class="pointer">
{{'candidates.available_from' | translate }}
</th>
<th class="pointer">
{{'candidates.status' | translate }}
</th>
<th>
{{'candidates.show.note' | translate}}
</th>
</tr>
</thead>
<tbody>
<tr class="change-height"
ng-class="{'contact-not-allowed': !candidate.contact_allowed, 'is-deal': candidate.is_deal }"
ng-repeat="candidate in project.candidates" id="candidate_row">
<td>
<a ui-sref='candidates.show({id: candidate.id})' href="#">{{ ::candidate.forename + ' ' + candidate.surname }}</a>
<i ng-if="$root.reminders_entities.candidates.indexOf(candidate.id) != -1" title="Posiada aktywne przypomnienie." class="fa fa-exclamation-circle" style="color: #ff0000;"></i>
</td>
<td>{{candidate.assignment_status_log[0].hourly_rate == null ? "" : candidate.assignment_status_log[0].hourly_rate}}
{{candidate.assignment_status_log[0].hourly_currency == null ? "-" : candidate.assignment_status_log[0].hourly_currency}} /
{{candidate.assignment_status_log[0].annual_rate == null ? "" : candidate.assignment_status_log[0].annual_rate}}
{{candidate.assignment_status_log[0].annual_currency == null ? "-" : candidate.assignment_status_log[0].annual_currency}}
</td>
<td>{{ candidate.assignment_status_log[0].available_from | date}}</td>
<td>{{ candidate.assignment_status_log[0].status | translate}}</td>
<td>
<div class="row">
<div class="col-md-12" ng-bind-html="candidate.assignment_status_log[0].note | autoLinker">
</div>
</div>
</td>
</tr>
</tbody>
</table>
</td>
<td>
<div class="btn-group-vertical">
<button title="{{'button_titles.add_reminder' | translate }}"
add-reminder-modal entity-type="Project"
entity-id="{{project.id}}" class="btn btn-info" type="button">
<i class="fa fa-calendar-plus-o"></i>
</button>
<a title="{{'button_titles.show_project' | translate }}"
ui-sref='projects.show({id: project.id})' href="#"
class="btn btn-primary" type="button">
<i class="glyphicon glyphicon-eye-open"></i>
</a>
<a ng-if="canEdit(project.concerns_current_user)"
title="{{'button_titles.edit_project' | translate }}"
ui-sref='projects.edit({id: project.id})' href="#"
class="btn btn-success" type="button">
<i class="glyphicon glyphicon-pencil"></i>
</a>
<a ng-if="canRemove(project.concerns_current_user)"
title="{{'button_titles.delete_project' | translate }}"
delete-confirmation-modal type="button" class="btn btn-danger"
data-resource-id="{{::project.id}}"
data-resource-name="{{::project.name}}"
data-resource-index="{{$index}}"
data-remove-callback="removeCallback({param: resource})">
<i class="glyphicon glyphicon-trash"></i>
</a>
</div>
</td>
</tr>
</tbody>
</table>
Вот так реализовано скачивание
let wb = XLSX.utils.table_to_book(document.getElementById('mytable'), {sheet:"Sheet JS"});
let wbout = XLSX.write(wb, {bookType:'xlsx', bookSST:true, type: 'binary'});
function s2ab(s) {
let buf = new ArrayBuffer(s.length);
let view = new Uint8Array(buf);
for (let i=0; i<s.length; i++) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
$("#btnExport").click(function(){
saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), 'test.xlsx');
});
И вот что получаю:
{{'projects.labels.actions' | translate }}
С помощью table2excel получал всю таблицу. Подскажите как получить всю таблицу с помощью SheetJS. Возможно переписать какой-то метод по примеру table2excel?