Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

View Reports in Excel, CSV, XLSX, XLS, XLS formats #1029

Merged
merged 1 commit into from
Aug 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/components/ADempiere/FileRender/EmptyFile/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!--
ADempiere-Vue (Frontend) for ADempiere ERP & CRM Smart Business Solution
Copyright (C) 2017-Present E.R.P. Consultores y Asociados, C.A.
Contributor(s): Edwin Betancourt [email protected] www.erpya.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https:www.gnu.org/licenses/>.
-->

<template>
<div class="empty-content" />
</template>

<script>
import { defineComponent } from '@vue/composition-api'
export default defineComponent({
name: 'Empty-File'
})
</script>

<style lang="scss" scoped>
.empty-content {
width: 100%;
height: 90%;
padding-right: 10px;
}
</style>
159 changes: 159 additions & 0 deletions src/components/ADempiere/FileRender/ExcelFile/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<!--
ADempiere-Vue (Frontend) for ADempiere ERP & CRM Smart Business Solution
Copyright (C) 2017-Present E.R.P. Consultores y Asociados, C.A.
Contributor(s): Edwin Betancourt [email protected] www.erpya.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https:www.gnu.org/licenses/>.
-->

<template>
<div class="content-excel">
<el-container class="sub-content-excel">
<el-main style="padding: 0;">
<el-button
style="margin:0 0 20px 20px;"
type="primary"
icon="el-icon-download"
@click="handleDownload"
>
{{ $t('components.contextMenuDownload') }}
</el-button>

<el-table
:data="excelData.results"
border
highlight-current-row
style="width: 100%;height: 85% !important;"
height="90% !important"
>
<el-table-column
v-for="item of excelData.header"
:key="item"
:label="item"
>
<template slot-scope="scope">
{{ scope.row[item] }} {{ item }}
</template>
</el-table-column>
</el-table>

</el-main>
</el-container>
</div>
</template>

<script>
import { defineComponent, ref } from '@vue/composition-api'
import XLSX from 'xlsx'
import { exportFileFromJson } from '@/utils/ADempiere/exportUtil.js'
export default defineComponent({
name: 'ExcelFile',
props: {
mimeType: {
type: String,
default: undefined
},
format: {
type: String,
default: 'xlsx'
},
name: {
type: String,
default: undefined
},
stream: {
type: [Object, Array],
required: true
}
},
setup(props) {
const excelData = ref({})
function downloadWithLink() {
let link = {
href: undefined,
download: undefined
}
const reportObject = Object.values(props.stream)
const blob = new Blob([Uint8Array.from(reportObject)], {
type: props.mimeType
})
link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = `${props.name}.${props.format}`
// download report file
link.click()
}
function handleDownload() {
const header = excelData.value.header
const data = excelData.value.results
return new Promise((resolve) => {
const file = exportFileFromJson({
header,
data,
isFormat: false,
fileName: props.name,
exportType: props.format
})
resolve(file)
})
}
function getHeaderRow(sheet) {
const headers = []
const range = XLSX.utils.decode_range(sheet['!ref'])
let C
const R = range.s.r
/* start in the first row */
for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]
/* find the cell in the first row */
let hdr = 'UNKNOWN ' + C // <-- replace with your desired default
if (cell && cell.t) {
hdr = XLSX.utils.format_cell(cell)
}
headers.push(hdr)
}
return headers
}
function generateReaderData() {
const data = Object.values(props.stream)
const blob = new Blob([
Uint8Array.from(data)
], {
type: props.mimeType
})
return new Promise((resolve) => {
const reader = new FileReader()
reader.onload = (e) => {
const workbook = XLSX.read(data, { type: 'array' })
const firstSheetName = workbook.SheetNames[0]
const worksheet = workbook.Sheets[firstSheetName]
const header = getHeaderRow(worksheet)
const results = XLSX.utils.sheet_to_json(worksheet)
// value to render
excelData.value = {
header,
results
}
resolve()
}
reader.readAsArrayBuffer(blob)
})
}
generateReaderData()
return {
excelData,
// methods
downloadWithLink,
handleDownload
}
}
})
</script>
59 changes: 59 additions & 0 deletions src/components/ADempiere/FileRender/HtmlFile/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<!--
ADempiere-Vue (Frontend) for ADempiere ERP & CRM Smart Business Solution
Copyright (C) 2017-Present E.R.P. Consultores y Asociados, C.A.
Contributor(s): Edwin Betancourt [email protected] www.erpya.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https:www.gnu.org/licenses/>.
-->

<template>
<div class="html-content">
<el-container class="sub-content-html">
<el-main style="padding: 0;">
<div
class="el-table--striped el-table--border el-table--scrollable-y el-table--scrollable-x"
v-html="content"
/>
</el-main>
</el-container>
</div>
</template>

<script>
import { defineComponent } from '@vue/composition-api'
export default defineComponent({
name: 'HTML-TXT-File',
props: {
content: {
type: [Object, String],
required: true
}
}
})
</script>

<style lang="scss" scoped>
.html-content {
width: 100%;
height: inherit;
padding-left: 10px;
padding-right: 10px;
.sub-content-html {
min-height: inherit;
height: inherit;
max-height: -webkit-max-content;
max-height: -moz-max-content;
max-height: max-content;
width: 100%;
padding-bottom: 4%;
}
}
</style>
45 changes: 45 additions & 0 deletions src/components/ADempiere/FileRender/PdfFile/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!--
ADempiere-Vue (Frontend) for ADempiere ERP & CRM Smart Business Solution
Copyright (C) 2017-Present E.R.P. Consultores y Asociados, C.A.
Contributor(s): Edwin Betancourt [email protected] www.erpya.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https:www.gnu.org/licenses/>.
-->

<template>
<iframe
class="pdf-content"
:src="src"
width="100%"
height="100%"
/>
</template>

<script>
import { defineComponent } from '@vue/composition-api'
export default defineComponent({
name: 'PDF-File',
props: {
src: {
type: String,
required: true
}
}
})
</script>

<style lang="scss" scoped>
.pdf-content {
width: 100%;
height: 90%;
padding-right: 10px;
}
</style>
87 changes: 87 additions & 0 deletions src/components/ADempiere/FileRender/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<!--
ADempiere-Vue (Frontend) for ADempiere ERP & CRM Smart Business Solution
Copyright (C) 2017-Present E.R.P. Consultores y Asociados, C.A.
Contributor(s): Edwin Betancourt [email protected] www.erpya.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https:www.gnu.org/licenses/>.
-->

<template>
<component
:is="componentRender"
:format="format"
:src="src"
:content="content"
:name="name"
:mime-type="mimeType"
:stream="stream"
/>
</template>

<script>
import { defineComponent, computed } from '@vue/composition-api'
export default defineComponent({
name: 'FileRender',
props: {
format: {
type: String,
required: true
},
content: {
type: [Object, Array, String, Number],
default: ''
},
src: {
type: [Object, Array, String],
default: ''
},
// excel file
name: {
type: String,
default: undefined
},
mimeType: {
type: String,
default: undefined
},
stream: {
type: [Object, Array],
default: undefined
}
},
setup(props) {
const componentRender = computed(() => {
let viewer
switch (props.format) {
case 'html':
case 'txt':
viewer = () => import('@/components/ADempiere/FileRender/HtmlFile')
break
case 'pdf':
viewer = () => import('@/components/ADempiere/FileRender/PdfFile')
break
case 'csv':
case 'xls':
case 'xlsx':
viewer = () => import('@/components/ADempiere/FileRender/ExcelFile')
break
default:
viewer = () => import('@/components/ADempiere/FileRender/EmptyFile')
break
}
return viewer
})
return {
componentRender
}
}
})
</script>
Loading