mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Server side export report
Add PDF and Excel export for report Change generation of CSV to laravel-excel Remove dompdf to use mpdf instand
This commit is contained in:
parent
0997f94cbc
commit
8ace6ad1ea
@ -8,6 +8,7 @@ use Input;
|
||||
use Str;
|
||||
use Utils;
|
||||
use View;
|
||||
use Excel;
|
||||
|
||||
/**
|
||||
* Class ReportController.
|
||||
@ -53,6 +54,7 @@ class ReportController extends BaseController
|
||||
}
|
||||
|
||||
$action = Input::get('action');
|
||||
$format = Input::get('format');
|
||||
|
||||
if (Input::get('report_type')) {
|
||||
$reportType = Input::get('report_type');
|
||||
@ -104,7 +106,7 @@ class ReportController extends BaseController
|
||||
$params['report'] = $report;
|
||||
$params = array_merge($params, $report->results());
|
||||
if ($isExport) {
|
||||
return self::export($reportType, $params['displayData'], $params['columns'], $params['reportTotals']);
|
||||
return self::export($format, $reportType, $params);
|
||||
}
|
||||
} else {
|
||||
$params['columns'] = [];
|
||||
@ -117,56 +119,81 @@ class ReportController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $format
|
||||
* @param $reportType
|
||||
* @param $data
|
||||
* @param $columns
|
||||
* @param $totals
|
||||
* @param $params
|
||||
* @todo: Add summary to export
|
||||
*/
|
||||
private function export($reportType, $data, $columns, $totals)
|
||||
private function export($format, $reportType, $params)
|
||||
{
|
||||
if (! Auth::user()->hasPermission('view_all')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$date = date('Y-m-d');
|
||||
$format = strtolower($format);
|
||||
$data = $params['displayData'];
|
||||
$columns = $params['columns'];
|
||||
$totals = $params['reportTotals'];
|
||||
$report = $params['report'];
|
||||
|
||||
$callback = function() use ($data, $columns) {
|
||||
$output = fopen('php://output', 'w') or Utils::fatalError();
|
||||
$filename = "{$params['startDate']}-{$params['endDate']}_invoiceninja-".strtolower(trans("texts.$reportType"))."-report";
|
||||
|
||||
$columns = array_map(function($key, $val) {
|
||||
return is_array($val) ? $key : $val;
|
||||
}, array_keys($columns), $columns);
|
||||
|
||||
Utils::exportData($output, $data, Utils::trans($columns));
|
||||
};
|
||||
|
||||
/*
|
||||
fwrite($output, trans('texts.totals'));
|
||||
foreach ($totals as $currencyId => $fields) {
|
||||
foreach ($fields as $key => $value) {
|
||||
fwrite($output, ',' . trans("texts.{$key}"));
|
||||
}
|
||||
fwrite($output, "\n");
|
||||
break;
|
||||
$formats = ['csv', 'pdf', 'xlsx'];
|
||||
if(!in_array($format, $formats)) {
|
||||
throw new \Exception("Invalid format request to export report");
|
||||
}
|
||||
|
||||
foreach ($totals as $currencyId => $fields) {
|
||||
$csv = Utils::getFromCache($currencyId, 'currencies')->name . ',';
|
||||
foreach ($fields as $key => $value) {
|
||||
$csv .= '"' . Utils::formatMoney($value, $currencyId).'",';
|
||||
}
|
||||
fwrite($output, $csv."\n");
|
||||
}
|
||||
*/
|
||||
//Get labeled header
|
||||
$report->tableHeaderArray();
|
||||
|
||||
$headers = [
|
||||
'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
|
||||
'Content-type' => 'text/csv',
|
||||
'Content-Disposition' => "attachment; filename={$date}-invoiceninja-{$reportType}-report.csv",
|
||||
'Expires' => '0',
|
||||
'Pragma' => 'public'
|
||||
];
|
||||
/*$summary = [];
|
||||
if(count(array_values($totals))) {
|
||||
$summary[] = array_merge([
|
||||
trans("texts.totals")
|
||||
], array_map(function ($key) {return trans("texts.{$key}");}, array_keys(array_values(array_values($totals)[0])[0])));
|
||||
}
|
||||
|
||||
return response()->stream($callback, 200, $headers);
|
||||
foreach ($totals as $currencyId => $each) {
|
||||
foreach ($each as $dimension => $val) {
|
||||
$tmp = [];
|
||||
$tmp[] = Utils::getFromCache($currencyId, 'currencies')->name . (($dimension) ? ' - ' . $dimension : '');
|
||||
|
||||
foreach ($val as $id => $field) $tmp[] = Utils::formatMoney($field, $currencyId);
|
||||
|
||||
$summary[] = $tmp;
|
||||
}
|
||||
}
|
||||
|
||||
dd($summary);*/
|
||||
|
||||
return Excel::create($filename, function($excel) use($report, $data, $reportType, $format) {
|
||||
$excel->sheet(trans("texts.$reportType"), function($sheet) use($report, $data, $format) {
|
||||
|
||||
$sheet->setOrientation('landscape');
|
||||
$sheet->freezeFirstRow();
|
||||
|
||||
//Add border on PDF
|
||||
if($format == 'pdf')
|
||||
$sheet->setAllBorders('thin');
|
||||
|
||||
$sheet->rows(array_merge(
|
||||
[array_map(function($col) {return $col['label'];}, $report->columns_labeled)],
|
||||
$data
|
||||
));
|
||||
|
||||
//Styling header
|
||||
$sheet->cells('A1:'.Utils::num2alpha(count($report->columns_labeled)-1).'1', function($cells) {
|
||||
$cells->setBackground('#777777');
|
||||
$cells->setFontColor('#FFFFFF');
|
||||
$cells->setFontSize(14);
|
||||
$cells->setFontFamily('Calibri');
|
||||
$cells->setFontWeight('bold');
|
||||
});
|
||||
|
||||
|
||||
$sheet->setAutoSize(true);
|
||||
});
|
||||
})->export($format);
|
||||
}
|
||||
}
|
||||
|
@ -1241,4 +1241,12 @@ class Utils
|
||||
fclose($handle);
|
||||
return( ord($contents[28]) != 0 );
|
||||
}
|
||||
|
||||
//Source: https://stackoverflow.com/questions/3302857/algorithm-to-get-the-excel-like-column-name-of-a-number
|
||||
public static function num2alpha($n)
|
||||
{
|
||||
for($r = ""; $n >= 0; $n = intval($n / 26) - 1)
|
||||
$r = chr($n%26 + 0x41) . $r;
|
||||
return $r;
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,6 @@
|
||||
"digitickets/omnipay-realex": "~5.0",
|
||||
"dioscouri/omnipay-cybersource": "dev-master",
|
||||
"doctrine/dbal": "2.5.x",
|
||||
"dompdf/dompdf": "^0.8.0",
|
||||
"ezyang/htmlpurifier": "~v4.7",
|
||||
"fotografde/omnipay-checkoutcom": "~2.0",
|
||||
"fruitcakestudio/omnipay-sisow": "~2.0",
|
||||
@ -67,6 +66,7 @@
|
||||
"meebio/omnipay-creditcall": "dev-master",
|
||||
"meebio/omnipay-secure-trading": "dev-master",
|
||||
"mfauveau/omnipay-pacnet": "~2.0",
|
||||
"mpdf/mpdf": "^6.1",
|
||||
"nwidart/laravel-modules": "^1.14",
|
||||
"omnipay/2checkout": "dev-master#e9c079c2dde0d7ba461903b3b7bd5caf6dee1248",
|
||||
"omnipay/bitpay": "dev-master",
|
||||
|
650
composer.lock
generated
650
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,21 @@
|
||||
<?php
|
||||
//https://github.com/PHPOffice/PHPExcel/issues/556#issuecomment-216722159
|
||||
switch (PHP_OS) {
|
||||
case 'WINNT':
|
||||
PHPExcel_Shared_Font::setTrueTypeFontPath('C:/Windows/Fonts/');
|
||||
PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);
|
||||
break;
|
||||
|
||||
case 'Darwin':
|
||||
PHPExcel_Shared_Font::setTrueTypeFontPath('/Library/Fonts/');
|
||||
PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);
|
||||
break;
|
||||
|
||||
case 'Linux':
|
||||
PHPExcel_Shared_Font::setTrueTypeFontPath('/usr/share/fonts/truetype/');
|
||||
PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);
|
||||
break;
|
||||
}
|
||||
|
||||
return array(
|
||||
|
||||
@ -171,7 +188,7 @@ return array(
|
||||
| having the appropriate fonts installed.
|
||||
|
|
||||
*/
|
||||
'autosize-method' => PHPExcel_Shared_Font::AUTOSIZE_METHOD_APPROX,
|
||||
'autosize-method' => PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@ -291,7 +308,7 @@ return array(
|
||||
|--------------------------------------------------------------------------
|
||||
| Supported: DomPDF, tcPDF, mPDF
|
||||
*/
|
||||
'driver' => 'DomPDF',
|
||||
'driver' => 'mPDF',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
@ -2392,7 +2392,7 @@ $LANG = array(
|
||||
'tax1' => 'First Tax',
|
||||
'tax2' => 'Second Tax',
|
||||
'fee_help' => 'Gateway fees are the costs charged for access to the financial networks that handle the processing of online payments.',
|
||||
'download_pdf' => 'Download PDF'
|
||||
'format_export' => 'Exporting format'
|
||||
|
||||
);
|
||||
|
||||
|
@ -16,11 +16,6 @@
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@foreach ($account->getFontFolders() as $font)
|
||||
<script src="{{ asset('js/vfs_fonts/'.$font.'.js') }}" type="text/javascript"></script>
|
||||
@endforeach
|
||||
<script src="{{ asset('pdf.built.js') }}?no_cache={{ NINJA_VERSION }}" type="text/javascript"></script>
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
@ -38,7 +33,6 @@
|
||||
var chartStartDate = moment("{{ $startDate }}");
|
||||
var chartEndDate = moment("{{ $endDate }}");
|
||||
var dateRanges = {!! $account->present()->dateRangeOptions !!};
|
||||
window.invoiceFonts = {!! json_encode(Cache::get('fonts')) !!};
|
||||
|
||||
$(function () {
|
||||
|
||||
@ -164,12 +158,9 @@
|
||||
|
||||
|
||||
<center>
|
||||
@if(request()->report_type)
|
||||
{!! Button::warning(trans('texts.download_pdf'))
|
||||
->withAttributes(array('onclick' => 'exportPDF()'))
|
||||
->appendIcon(Icon::create('save'))
|
||||
->large() !!}
|
||||
@endif
|
||||
{!! Former::select('format')
|
||||
->label(trans('texts.format_export'))
|
||||
->options(['csv' => 'CSV', 'pdf' => 'PDF', 'xlsx' => 'Excel']) !!}
|
||||
{!! Button::primary(trans('texts.export'))
|
||||
->withAttributes(array('onclick' => 'onExportClick()'))
|
||||
->appendIcon(Icon::create('export'))
|
||||
@ -364,131 +355,6 @@
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
<?php
|
||||
|
||||
$summary = [];
|
||||
if(count(array_values($reportTotals))) {
|
||||
$summary[] = array_merge([
|
||||
trans("texts.totals")
|
||||
], array_map(function ($key) {
|
||||
return ['text' => trans("texts.{$key}"),
|
||||
'style' => 'tableHeader'
|
||||
];
|
||||
}, array_keys(array_values(array_values($reportTotals)[0])[0])));
|
||||
}
|
||||
|
||||
foreach ($reportTotals as $currencyId => $each) {
|
||||
foreach ($each as $dimension => $val) {
|
||||
$tmp = [];
|
||||
$tmp[] = Utils::getFromCache($currencyId, 'currencies')->name . (($dimension) ? ' - ' . $dimension : '');
|
||||
|
||||
foreach ($val as $id => $field) $tmp[] = Utils::formatMoney($field, $currencyId);
|
||||
|
||||
$summary[] = $tmp;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
function addFont(font){
|
||||
if(window.ninjaFontVfs[font.folder]){
|
||||
folder = 'fonts/'+font.folder;
|
||||
pdfMake.fonts[font.name] = {
|
||||
normal: folder+'/'+font.normal,
|
||||
italics: folder+'/'+font.italics,
|
||||
bold: folder+'/'+font.bold,
|
||||
bolditalics: folder+'/'+font.bolditalics
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pdfMake.fonts = {}
|
||||
fonts = window.invoiceFonts || invoice.invoice_fonts;
|
||||
|
||||
// Add only the loaded fonts
|
||||
$.each(fonts, function(i,font){
|
||||
addFont(font);
|
||||
});
|
||||
var dd = {!! html_entity_decode(json_encode( [
|
||||
'pageOrientation' => 'landscape',
|
||||
'content' => [
|
||||
[
|
||||
'text' => $reportTypes[$reportType],
|
||||
'style' => 'header'
|
||||
],
|
||||
[
|
||||
'style' => 'reportTable',
|
||||
'table' => [
|
||||
'headerRows' => 1,
|
||||
'widths' => '*',
|
||||
'body' => $summary
|
||||
],
|
||||
'layout' => 'lightHorizontalLines'
|
||||
],
|
||||
[
|
||||
'style' => 'reportTable',
|
||||
'table' => [
|
||||
'headerRows' => 1,
|
||||
'widths' => '*',
|
||||
'body' =>
|
||||
array_merge(
|
||||
[array_map(function($array) {
|
||||
return [
|
||||
'text' => $array['label'],
|
||||
'style' => 'tableHeader'
|
||||
];
|
||||
}, $report->columns_labeled)]
|
||||
, array_map(function($row) {
|
||||
return array_map(function($col) {
|
||||
if(strpos($col, "<a href") !== FALSE) {
|
||||
$hrefs = [];
|
||||
preg_match('#<a.*href=[\'"](.*)["\'].*>(.*)<.*#', $col, $hrefs);
|
||||
return [
|
||||
'text' => $hrefs[2],
|
||||
'link' => $hrefs[1]
|
||||
];
|
||||
}
|
||||
return $col;
|
||||
}, $row);
|
||||
}, $displayData))
|
||||
|
||||
],
|
||||
'layout' => 'lightHorizontalLines'
|
||||
]
|
||||
],
|
||||
'styles' => [
|
||||
'header' => [
|
||||
'fontSize' => 18,
|
||||
'bold' => true,
|
||||
'margin' => [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
10
|
||||
]
|
||||
],
|
||||
'reportTable' => [
|
||||
'margin' => [
|
||||
0,
|
||||
5,
|
||||
0,
|
||||
50
|
||||
]
|
||||
],
|
||||
'tableHeader' => [
|
||||
'bold' => true,
|
||||
'fontSize' => 13,
|
||||
'color' => 'black'
|
||||
]
|
||||
],
|
||||
'defaultStyle' => [
|
||||
'font' => Cache::get('fonts')[0]['name']
|
||||
]
|
||||
] , JSON_PRETTY_PRINT)) !!}
|
||||
function exportPDF() {
|
||||
pdfMake.createPdf(dd).download($('#reportrange').data('daterangepicker').startDate.format('YYYY-MM-DD') + '-' + $('#reportrange').data('daterangepicker').endDate.format('YYYY-MM-DD')+'_'+'{{'-invoiceninja-'.$reportTypes[$reportType].'-report'}}');
|
||||
}
|
||||
</script>
|
||||
@stop
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user