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 Str;
|
||||||
use Utils;
|
use Utils;
|
||||||
use View;
|
use View;
|
||||||
|
use Excel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ReportController.
|
* Class ReportController.
|
||||||
@ -53,6 +54,7 @@ class ReportController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
$action = Input::get('action');
|
$action = Input::get('action');
|
||||||
|
$format = Input::get('format');
|
||||||
|
|
||||||
if (Input::get('report_type')) {
|
if (Input::get('report_type')) {
|
||||||
$reportType = Input::get('report_type');
|
$reportType = Input::get('report_type');
|
||||||
@ -104,7 +106,7 @@ class ReportController extends BaseController
|
|||||||
$params['report'] = $report;
|
$params['report'] = $report;
|
||||||
$params = array_merge($params, $report->results());
|
$params = array_merge($params, $report->results());
|
||||||
if ($isExport) {
|
if ($isExport) {
|
||||||
return self::export($reportType, $params['displayData'], $params['columns'], $params['reportTotals']);
|
return self::export($format, $reportType, $params);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$params['columns'] = [];
|
$params['columns'] = [];
|
||||||
@ -117,56 +119,81 @@ class ReportController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param $format
|
||||||
* @param $reportType
|
* @param $reportType
|
||||||
* @param $data
|
* @param $params
|
||||||
* @param $columns
|
* @todo: Add summary to export
|
||||||
* @param $totals
|
|
||||||
*/
|
*/
|
||||||
private function export($reportType, $data, $columns, $totals)
|
private function export($format, $reportType, $params)
|
||||||
{
|
{
|
||||||
if (! Auth::user()->hasPermission('view_all')) {
|
if (! Auth::user()->hasPermission('view_all')) {
|
||||||
exit;
|
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) {
|
$filename = "{$params['startDate']}-{$params['endDate']}_invoiceninja-".strtolower(trans("texts.$reportType"))."-report";
|
||||||
$output = fopen('php://output', 'w') or Utils::fatalError();
|
|
||||||
|
|
||||||
$columns = array_map(function($key, $val) {
|
|
||||||
return is_array($val) ? $key : $val;
|
|
||||||
}, array_keys($columns), $columns);
|
|
||||||
|
|
||||||
Utils::exportData($output, $data, Utils::trans($columns));
|
$formats = ['csv', 'pdf', 'xlsx'];
|
||||||
};
|
if(!in_array($format, $formats)) {
|
||||||
|
throw new \Exception("Invalid format request to export report");
|
||||||
/*
|
|
||||||
fwrite($output, trans('texts.totals'));
|
|
||||||
foreach ($totals as $currencyId => $fields) {
|
|
||||||
foreach ($fields as $key => $value) {
|
|
||||||
fwrite($output, ',' . trans("texts.{$key}"));
|
|
||||||
}
|
|
||||||
fwrite($output, "\n");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($totals as $currencyId => $fields) {
|
//Get labeled header
|
||||||
$csv = Utils::getFromCache($currencyId, 'currencies')->name . ',';
|
$report->tableHeaderArray();
|
||||||
foreach ($fields as $key => $value) {
|
|
||||||
$csv .= '"' . Utils::formatMoney($value, $currencyId).'",';
|
/*$summary = [];
|
||||||
}
|
if(count(array_values($totals))) {
|
||||||
fwrite($output, $csv."\n");
|
$summary[] = array_merge([
|
||||||
|
trans("texts.totals")
|
||||||
|
], array_map(function ($key) {return trans("texts.{$key}");}, array_keys(array_values(array_values($totals)[0])[0])));
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
$headers = [
|
foreach ($totals as $currencyId => $each) {
|
||||||
'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
|
foreach ($each as $dimension => $val) {
|
||||||
'Content-type' => 'text/csv',
|
$tmp = [];
|
||||||
'Content-Disposition' => "attachment; filename={$date}-invoiceninja-{$reportType}-report.csv",
|
$tmp[] = Utils::getFromCache($currencyId, 'currencies')->name . (($dimension) ? ' - ' . $dimension : '');
|
||||||
'Expires' => '0',
|
|
||||||
'Pragma' => 'public'
|
|
||||||
];
|
|
||||||
|
|
||||||
return response()->stream($callback, 200, $headers);
|
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);
|
fclose($handle);
|
||||||
return( ord($contents[28]) != 0 );
|
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",
|
"digitickets/omnipay-realex": "~5.0",
|
||||||
"dioscouri/omnipay-cybersource": "dev-master",
|
"dioscouri/omnipay-cybersource": "dev-master",
|
||||||
"doctrine/dbal": "2.5.x",
|
"doctrine/dbal": "2.5.x",
|
||||||
"dompdf/dompdf": "^0.8.0",
|
|
||||||
"ezyang/htmlpurifier": "~v4.7",
|
"ezyang/htmlpurifier": "~v4.7",
|
||||||
"fotografde/omnipay-checkoutcom": "~2.0",
|
"fotografde/omnipay-checkoutcom": "~2.0",
|
||||||
"fruitcakestudio/omnipay-sisow": "~2.0",
|
"fruitcakestudio/omnipay-sisow": "~2.0",
|
||||||
@ -67,6 +66,7 @@
|
|||||||
"meebio/omnipay-creditcall": "dev-master",
|
"meebio/omnipay-creditcall": "dev-master",
|
||||||
"meebio/omnipay-secure-trading": "dev-master",
|
"meebio/omnipay-secure-trading": "dev-master",
|
||||||
"mfauveau/omnipay-pacnet": "~2.0",
|
"mfauveau/omnipay-pacnet": "~2.0",
|
||||||
|
"mpdf/mpdf": "^6.1",
|
||||||
"nwidart/laravel-modules": "^1.14",
|
"nwidart/laravel-modules": "^1.14",
|
||||||
"omnipay/2checkout": "dev-master#e9c079c2dde0d7ba461903b3b7bd5caf6dee1248",
|
"omnipay/2checkout": "dev-master#e9c079c2dde0d7ba461903b3b7bd5caf6dee1248",
|
||||||
"omnipay/bitpay": "dev-master",
|
"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
|
<?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(
|
return array(
|
||||||
|
|
||||||
@ -171,7 +188,7 @@ return array(
|
|||||||
| having the appropriate fonts installed.
|
| 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
|
| Supported: DomPDF, tcPDF, mPDF
|
||||||
*/
|
*/
|
||||||
'driver' => 'DomPDF',
|
'driver' => 'mPDF',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
@ -2392,7 +2392,7 @@ $LANG = array(
|
|||||||
'tax1' => 'First Tax',
|
'tax1' => 'First Tax',
|
||||||
'tax2' => 'Second 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.',
|
'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>
|
</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
|
@stop
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@ -38,7 +33,6 @@
|
|||||||
var chartStartDate = moment("{{ $startDate }}");
|
var chartStartDate = moment("{{ $startDate }}");
|
||||||
var chartEndDate = moment("{{ $endDate }}");
|
var chartEndDate = moment("{{ $endDate }}");
|
||||||
var dateRanges = {!! $account->present()->dateRangeOptions !!};
|
var dateRanges = {!! $account->present()->dateRangeOptions !!};
|
||||||
window.invoiceFonts = {!! json_encode(Cache::get('fonts')) !!};
|
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
@ -164,12 +158,9 @@
|
|||||||
|
|
||||||
|
|
||||||
<center>
|
<center>
|
||||||
@if(request()->report_type)
|
{!! Former::select('format')
|
||||||
{!! Button::warning(trans('texts.download_pdf'))
|
->label(trans('texts.format_export'))
|
||||||
->withAttributes(array('onclick' => 'exportPDF()'))
|
->options(['csv' => 'CSV', 'pdf' => 'PDF', 'xlsx' => 'Excel']) !!}
|
||||||
->appendIcon(Icon::create('save'))
|
|
||||||
->large() !!}
|
|
||||||
@endif
|
|
||||||
{!! Button::primary(trans('texts.export'))
|
{!! Button::primary(trans('texts.export'))
|
||||||
->withAttributes(array('onclick' => 'onExportClick()'))
|
->withAttributes(array('onclick' => 'onExportClick()'))
|
||||||
->appendIcon(Icon::create('export'))
|
->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>
|
</script>
|
||||||
@stop
|
@stop
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user