This commit is contained in:
2026-01-13 12:46:07 +03:00
commit cc8716fa74
364 changed files with 88316 additions and 0 deletions

38
src/App.vue Normal file
View File

@@ -0,0 +1,38 @@
<style>
html,
body,
#myContainer {
height: 100%;
width: 100%;
background: url(../../../_libs/images/Fonoviy.png) left top repeat !important;
}
.myContainer {
height: 100%;
width: 100%;
background: url(../../../_libs/images/Fonoviy.png) left top repeat !important;
}
</style>
<template>
<v-app>
<v-main>
<router-view></router-view>
</v-main>
</v-app>
</template>
<script>
export default {
name: "App",
data: () => ({
}),
mounted() {
},
};
</script>

23
src/api/index.js Normal file
View File

@@ -0,0 +1,23 @@
import Vue from "vue";
import VueAxios from "vue-axios";
import axios from "axios";
//12
switch (process.env.NODE_ENV) {
case "development":
axios.defaults.baseURL =
"http://192.168.76.112//_api_server_vue/index.php";
break;
case "production":
axios.defaults.baseURL =
"http://192.168.76.100:81//_api_server_vue/index.php";
break;
}
axios.defaults.method = "POST";
axios.defaults.headers.common["Authorization"] = "*";
Vue.use(VueAxios, axios);

BIN
src/assets/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

BIN
src/assets/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 KiB

BIN
src/assets/4.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

BIN
src/assets/99.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
src/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

1
src/assets/logo.svg Normal file
View File

@@ -0,0 +1 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 87.5 100"><defs><style>.cls-1{fill:#1697f6;}.cls-2{fill:#7bc6ff;}.cls-3{fill:#1867c0;}.cls-4{fill:#aeddff;}</style></defs><title>Artboard 46</title><polyline class="cls-1" points="43.75 0 23.31 0 43.75 48.32"/><polygon class="cls-2" points="43.75 62.5 43.75 100 0 14.58 22.92 14.58 43.75 62.5"/><polyline class="cls-3" points="43.75 0 64.19 0 43.75 48.32"/><polygon class="cls-4" points="64.58 14.58 87.5 14.58 43.75 100 43.75 62.5 64.58 14.58"/></svg>

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View File

@@ -0,0 +1,612 @@
<template>
<v-container fluid id="BOFHeatPhase">
<v-card-text class="text-center headline black--text">Циклограмма производства {{ BofSelect }} в ККЦ за период
{{ computedDateFormatted }}</v-card-text>
<v-divider class="mx-0"></v-divider>
<v-row>
<v-col style="min-width:250px; max-width:250px;" cols="12">
<v-menu v-model="datePickerMenu" :close-on-content-click="false" :nudge-right="40" :nudge-top="-5"
transition="scale-transition" offset-y min-width="290px">
<template v-slot:activator="{ on }">
<v-text-field id="datePicker" class="datePicker" v-model="computedDateFormatted" prepend-icon="event"
readonly v-on="on" single-line :disabled="loading" />
</template>
<v-date-picker no-title scrollable popover-align="center" v-model="dates"
@input="input($event) && datePickerMenu" @change="refreshData()" range></v-date-picker>
</v-menu>
</v-col>
<!-- <v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col class="text-center my-4" cols="1" sm="1">
<v-btn tile outlined color="success" :disabled="loading || !data.table.length" @click="loader = Excel()">
<v-icon left size="35">mdi-file-excel</v-icon>Excel
</v-btn>
</v-col> -->
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col style="min-width:220px; max-width:220px;" cols="12">
<v-select v-model="BofSelect" :items="listBof" persistent-hint @change="changeBOFselect()" density="compact"
:disabled="loading">
<template v-slot:selection="{ index }">
<span v-if="index === 0">{{ "№ конвертера: " + BofSelect + "" }}</span>
</template>
</v-select>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col class="text-center my-4" cols="1" sm="1">
<v-btn tile outlined color="success" :disabled="loading || !data.table.length" @click="loader = toImage()">
<v-icon left size="35">mdi-file-image</v-icon>PNG
</v-btn>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col class="text-center my-4" cols="1" sm="1">
<v-btn tile outlined color="success" :disabled="loading || !data.table.length" @click="loader = toPrint()">
<v-icon left size="35">mdi-printer</v-icon>Печать
</v-btn>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col>
<v-checkbox v-model="checkbox" :disabled="loading" label="Автообновление (5 мин)"
@click="loader = autoRefresh(checkbox)">
</v-checkbox>
</v-col>
</v-row>
<v-divider class="mx-0"></v-divider>
<v-progress-linear v-if="loading" indeterminate></v-progress-linear>
<v-progress-linear v-if="checkbox && !loading" color="orange" rounded :value="progress"
reactive></v-progress-linear>
<v-container fluid :style="{ 'height': barHeight + 'px' }">
<Bar v-if="chartData.datasets.length" :options="chartOptions" :data="chartData" ref="bar" />
</v-container>
<v-container fluid>
<v-expansion-panels v-if="data.table.length" v-show="!loading" :disabled="loading" tile focusable>
<v-expansion-panel>
<v-expansion-panel-header>
<span>
<v-icon>info</v-icon>
Простои подробнее...
</span>
</v-expansion-panel-header>
<v-expansion-panel-content class="my-5">
<v-data-table v-model="selected" @input="prostoiSelect()" :headers="headers" :items="data.table"
disable-pagination hide-default-footer :item-class="row_classes" dense fixed-header show-select
item-key="id" group-by='Agregat'>
<template v-slot:top>
<v-progress-linear v-if="loading" indeterminate></v-progress-linear>
</template>
<template v-slot:item.data-table-select="{ item, isSelected, select }">
<v-simple-checkbox v-show="item.Descr == 'Простой'" :value="isSelected" :readonly="item.disabled"
@input="select($event)"> </v-simple-checkbox>
</template>
</v-data-table>
</v-expansion-panel-content>
</v-expansion-panel>
</v-expansion-panels>
</v-container>
</v-container>
</template>
<script>
const jsDate = new Date();
import { mapGetters, mapActions, mapMutations } from "vuex";
import {
Chart as ChartJS,
Title,
Tooltip,
Legend,
BarElement,
CategoryScale,
LinearScale,
TimeScale
} from 'chart.js'
import { Bar } from 'vue-chartjs'
import 'chartjs-adapter-moment';
import ChartDataLabels from 'chartjs-plugin-datalabels';
ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend, ChartDataLabels, TimeScale);
export default {
name: 'BarChart',
components: {
Bar
},
data() {
return {
dates: [
new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() + 1)
.toISOString()
.substr(0, 10),
new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() + 1)
.toISOString()
.substr(0, 10),
],
// dates: [
// new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() + 1)
// .toISOString()
// .substr(0, 10),
// new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() + 1)
// .toISOString()
// .substr(0, 10),
// ],
BofSelect: 'K1+K2',
listBof: ['K1', 'K2', 'K1+K2'],
selected: [],
checkbox: false,
progress: 100,
timerDelay: 60,
datePickerMenu: false,
barHeight: 0,
chartData: {
// labels: [],
datasets: [],
},
chartOptions: {
plugins: {
legend: {
display: true,
//onClick: (e) => e.stopPropagation(),
onClick: false,
labels: {
// filter: function (item) {
// //if (item.text != '')
// return 'item'
// }
generateLabels() {
return [{
text: 'Простой, мин',
fillStyle: '#C2CBD1',
},
{
text: 'Конвертер, мин',
fillStyle: '#51C27F',
},
{
text: 'УПК, мин',
fillStyle: '#FF6F4D',
},
{
text: 'МНЛЗ - прибытие, мин',
fillStyle: '#00eeff',
},
{
text: 'МНЛЗ - разливка, мин',
fillStyle: '#01d5e4',
},
{
text: 'МНЛЗ - порезка, мин',
fillStyle: '#03a2ad',
}]
// const data = chart.data;
// if (data.labels.length && data.datasets.length) {
// const {labels: {pointStyle}} = chart.legend.options;
// return data.labels.map((label, i) => {
// const meta = chart.getDatasetMeta(0);
// const style = meta.controller.getStyle(i);
// return {
// text: `${label}: ${data['datasets'][0].data[i]}`,
// fillStyle: style.backgroundColor,
// strokeStyle: style.borderColor,
// lineWidth: style.borderWidth,
// pointStyle: pointStyle,
// hidden: !chart.getDataVisibility(i),
// // Extra data used for toggling the correct item
// index: i
// };
// });
// }
// return [];
}
},
},
title: {
display: true,
text: '',
align: 'center'
},
tooltip: {
callbacks: {
label: function (context) {
let label = '';
if (context.parsed.y !== null) {
if (context.dataset.aggregate === 'bof') {
label += 'Конвертер: ' + context.dataset.date_start + ' - ' + context.dataset.date_end
} else if (context.dataset.aggregate === 'prostoy') {
label += 'Простой: ' + context.dataset.data[context.dataIndex].prostoi_name + ' (' + context.dataset.p_start + ' - ' + context.dataset.p_end + ')'
} else if (context.dataset.aggregate === 'lf') {
label += 'УПК: ' + context.dataset.lf_start + ' - ' + context.dataset.lf_end
} else if (context.dataset.aggregate === 'ccm_status2') {
label += 'МНЛЗ - прибытие: ' + context.dataset.ccm_status2_start + ' - ' + context.dataset.ccm_status2_end
} else if (context.dataset.aggregate === 'ccm_status3') {
label += 'МНЛЗ - разливка: ' + context.dataset.ccm_status3_start + ' - ' + context.dataset.ccm_status3_end
} else if (context.dataset.aggregate === 'ccm_status4') {
label += 'МНЛЗ - порезка: ' + context.dataset.ccm_status4_start + ' - ' + context.dataset.ccm_status4_end
}
}
return label
}
}
},
datalabels: {
labels: {
name: {
//anchor: 'end',
//align: 'top',
color: 'black',
display: true,
font: { size: 12 },
formatter: function (value,) {
return value.PHASE_DURATION
}
},
value: {
color: 'black',
display: false,
padding: 2,
}
},
},
},
responsive: true,
maintainAspectRatio: false,
//aspectRatio: 12,
indexAxis: 'y',
scales: {
x: {
type: 'time',
//stacked: true,
time: {
displayFormats: {
'millisecond': 'MMM DD',
'second': 'MMM DD',
'minute': 'MMM DD',
'hour': 'HH:mm',
'day': 'MMM DD',
'week': 'MMM DD',
'month': 'MMM DD',
'quarter': 'MMM DD',
'year': 'MMM DD',
},
unit: 'hour',
//stepSize: '00:30',
},
// min: this.data.minDate,
// max: this.data.maxDate,
},
y: {
stacked: true,
ticks: {
callback: function () { }
}
// ticks: {
// callback: function (value, index, ticks) {
// console.log(index)
// console.log(ticks)
// // console.log(a)
// // console.log(c)
// // if (this.getLabelForValue(value)==='25K10867')
// // return this.getLabelForValue(value);
// if (this.getLabelForValue(value)==='25K10867')
// return this.getLabelForValue(value)
// },
// callback:this.myFunction(),
// }
},
},
}
}
},
computed: {
...mapGetters("BOFHeatPhase", {
loading: "loading",
data: "data"
}),
computedDateFormatted() {
let formatDates = [];
formatDates.push(this.formatDate(this.dates[0]));
formatDates.push(this.formatDate(this.dates[1]));
return formatDates.join(" ~ ");
},
headers() {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Roboto, sans-serif";
this.data.headers.forEach(element => {
var metrics = ctx.measureText(element.text);
var cellWidth = metrics.width;
element.width = cellWidth + 65;
element.divider = true;
element.align = "center";
if (element.value === "id") {
element.align = " d-none";
}
});
return this.data.headers;
},
},
methods: {
...mapMutations("BOFHeatPhase", {
getExcel: "getExcel",
}),
...mapActions("BOFHeatPhase", {
getData: "getData",
refreshChart: "refreshChart",
changeAggregate: "changeAggregate"
}),
toPrint() {
var canvasEle = this.$refs.bar.$el;
var win = window.open();
// win.document.write("<br><img width='99%' height='80%' src='" + canvasEle.toDataURL() + "' />");
win.document.write("<br><img width='99%' src='" + canvasEle.toDataURL() + "' />");
setTimeout(function () { //giving it 200 milliseconds time to load
// win.document.close();
// win.focus()
win.print();
// win.location.reload()
}, 0);
// let url = this.$refs.bar.$el.toDataURL();
// let win = window.open();
// win.document.write("<img class='a4-container' src='" + url + "'/>");
// win.setTimeout(() => win.print(), 0);
},
toImage() {
const context = this.$refs.bar.$el.getContext('2d');
context.save();
context.globalCompositeOperation = 'destination-over';
context.fillStyle = 'white';
context.fillRect(0, 0, this.$refs.bar.$el.width, this.$refs.bar.$el.height);
context.restore();
const link = document.createElement("a");
link.download = 'chart.png'
link.href = this.$refs.bar.$el.toDataURL('image/png')
link.click();
},
// Excel() {
// const context = this.$refs.bar.$el.getContext('2d');
// context.save();
// context.globalCompositeOperation = 'destination-over';
// context.fillStyle = 'white';
// context.fillRect(0, 0, this.$refs.bar.$el.width, this.$refs.bar.$el.height);
// context.restore();
// this.getExcel([
// this.formatDate(this.dates[0]),
// this.formatDate(this.dates[1]),
// this.$refs.bar.$el.toDataURL('image/png')
// ]);
// },
input(e) {
if (e.length == 2) {
this.datePickerMenu = false;
}
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
row_classes(item) {
if (item.Descr === 'Простой') {
return 'grey lighten-3';
}
},
setLabelText(val) {
let selected = val
this.chartOptions.scales.y.ticks.callback = function (value,) {
let labelText = this.getLabelForValue(value);
let descrText = '';
selected.forEach((element) => {
if (this.getLabelForValue(value) == element.heat_number) {
descrText = `${element.prostoi_descr}, `;
labelText = `${descrText.slice(0, -2)} (${element.phase_duration}) - ${this.getLabelForValue(value)}`;
}
})
return labelText
}
},
changeBOFselect() {
this.barHeight = 0;
this.chartData.labels = [];
this.chartData.datasets = [];
this.changeAggregate(this.BofSelect).then(() => {
this.refreshChart([this.selected, this.BofSelect]).then(() => {
this.chartData.datasets = this.data.chart.dataset;
this.setLabelText(this.data.prostoiSelected)
this.barHeight += 175 + (this.data.chart.label.length * 25);
this.chartOptions.plugins.title.text = `Циклограмма производства ${this.BofSelect} в ККЦ за ${this.formatDate(this.dates[0])}`;
});
});
// this.barHeight = 0;
// this.chartData.labels = [];
// this.chartData.datasets = [];
// this.refreshChart([this.selected, this.BofSelect]).then(() => {
// this.chartData.datasets = this.data.chart.dataset;
// this.setLabelText(this.data.prostoiSelected)
// this.barHeight += 175 + (this.data.chart.label.length * 25);
// });
},
prostoiSelect() {
this.chartData.datasets = [];
this.refreshChart([this.selected, this.BofSelect]).then(() => {
this.chartData.datasets = this.data.chart.dataset;
this.setLabelText(this.data.prostoiSelected)
});
},
refreshData() {
this.chartData.labels = [];
this.chartData.datasets = [];
this.barHeight = 0;
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]), this.dates[1]],
)
.then(() => {
let dStart = new Date(new Date(this.dates[0]).getFullYear(),
new Date(this.dates[0]).getMonth(),
new Date(this.dates[0]).getDate())
.toISOString()
.substr(0, 10) + ' 23:00:00';
let dEnd =
new Date(new Date(this.dates[1]).getFullYear(),
new Date(this.dates[1]).getMonth(),
new Date(this.dates[1]).getDate() + 1)
.toISOString()
.substr(0, 10) + ' 23:00:00';
//this.chartOptions.plugins.title.text = 'Циклограмма производства в ККЦ за ' + this.formatDate(this.dates[0]);
this.chartOptions.plugins.title.text = `Циклограмма производства ${this.BofSelect} в ККЦ за ${this.formatDate(this.dates[0])}`;
this.chartOptions.scales.x.min = dStart;
this.chartOptions.scales.x.max = dEnd;
this.selected = this.data.prostoiSelected
this.progress = 101;
}).then(() => {
// this.barHeight += 145 + (this.data.chart.label.length * 20);
this.refreshChart([this.selected]).then(() => {
this.barHeight += 175 + (this.data.chart.label.length * 25);
this.chartData.datasets = this.data.chart.dataset;
this.setLabelText(this.data.prostoiSelected);
});
})
},
autoRefresh(e) {
if (e) {
this.progress = 101;
this.progressValue();
} else {
clearInterval(this.timerID);
}
},
progressValue() {
this.timerID = setInterval(() => {
this.progress = (this.progress - 0.02).toFixed(2);
if (this.progress < 0) {
this.progress = 101;
this.refreshData();
}
}, this.timerDelay);
}
},
mounted() {
this.refreshData();
}
}
</script>
<style>
.datePicker input {
text-align: center;
cursor: pointer;
}
/* .theme--light.v-data-table tbody tr.v-data-table__selected {
background: #ffd296d2 !important;
}
.theme--dark.v-data-table tbody tr.v-data-table__selected {
background: #ffd296d2 !important;
} */
.a4-container {
width: 10mm !important;
height: 297mm !important;
margin: auto;
/* для центровки страницы */
page-break-after: always;
/* для начала следующего элемента с новой страницы */
}
#BOFHeatPhase .v-expansion-panel {
border-left: thin solid rgba(0, 0, 0, 0.12) !important;
border-right: thin solid rgba(0, 0, 0, 0.12) !important;
border-top: thin solid rgba(0, 0, 0, 0.12) !important;
border-bottom: thin solid rgba(0, 0, 0, 0.12) !important;
}
#BOFHeatPhase .v-expansion-panel::before {
box-shadow: none !important;
}
#BOFHeatPhase .v-data-table-header {
background-color: #fafafa !important;
}
#BOFHeatPhase .spacer {
margin-top: 3em;
}
#BOFHeatPhase .divider {
border-right: rgba(0, 0, 0, 0.12) solid 1px;
}
#BOFHeatPhase .v-data-table {
border-left: thin solid rgba(0, 0, 0, 0.12);
border-top: thin solid rgba(0, 0, 0, 0.12);
border-bottom: thin solid rgba(0, 0, 0, 0.12);
border-radius: 0;
}
#BOFHeatPhase .v-data-table table>tbody>tr>td {
border-right: thin solid rgba(0, 0, 0, 0.12);
}
#crewAggregateWeight #datePicker {
text-align: center;
}
/* #BOFHeatPhase .v-item-group.theme--light.v-expansion-panels.v-expansion-panels--focusable.v-expansion-panels--tile>div>div>div>div>div>table>thead>tr>th.text-start>div {
display: none;
} */
.theme--light.v-data-table tbody tr.v-data-table__selected {
background: #f5c17d70 !important;
}
.theme--dark.v-data-table tbody tr.v-data-table__selected {
background: #a17b4970 !important;
}
.theme--dark.v-data-table tbody tr.v-data-table__selected:hover {
background: #a17b49c2 !important;
}
.theme--light.v-data-table tbody tr.v-data-table__selected:hover {
background: #ffd296d2 !important;
}
</style>

View File

@@ -0,0 +1,280 @@
<template>
<v-container fluid id="BOFHeatPhase">
<v-card-text class="text-center headline black--text">Циклограмма плавок ККЦ за период
{{ computedDateFormatted }}</v-card-text>
<v-divider class="mx-0"></v-divider>
<v-row>
<v-col style="min-width:250px; max-width:250px;" cols="12">
<v-menu v-model="datePickerMenu" :close-on-content-click="false" :nudge-right="40" :nudge-top="-5"
transition="scale-transition" offset-y min-width="290px">
<template v-slot:activator="{ on }">
<v-text-field id="datePicker" class="datePicker" v-model="computedDateFormatted" prepend-icon="event"
readonly v-on="on" single-line :disabled="loading" />
</template>
<v-date-picker no-title scrollable popover-align="center" v-model="dates"
@input="input($event) && datePickerMenu" @change="refreshData()" range></v-date-picker>
</v-menu>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col class="text-center my-4" cols="1" sm="1">
<v-btn :disabled="true" tile outlined color="success" @click="loader = Excel()">
<v-icon left size="35">mdi-file-excel</v-icon>Excel
</v-btn>
</v-col>
</v-row>
<v-progress-linear v-if="loading" indeterminate></v-progress-linear>
<v-container :style="{ 'height': barHeight + 'px' }">
<Bar style="background-color: white;" v-if="chartData.datasets.length" :options="chartOptions" :data="chartData" ref="bar" />
</v-container>
</v-container>
</template>
<script>
let jsDate = new Date();
import { mapGetters, mapActions, mapMutations } from "vuex";
import {
Chart as ChartJS,
Title,
Tooltip,
Legend,
BarElement,
CategoryScale,
LinearScale,
TimeScale
} from 'chart.js'
import { Bar } from 'vue-chartjs'
import 'chartjs-adapter-moment';
import ChartDataLabels from 'chartjs-plugin-datalabels';
ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend, ChartDataLabels, TimeScale)
export default {
name: 'BarChart',
components: {
Bar
},
data() {
return {
dates: [
new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() + 1)
.toISOString()
.substr(0, 10),
new Date().toISOString().substr(0, 10)
],
datePickerMenu: false,
barHeight: 0,
chartData: {
labels: [],
datasets: [],
//labels: ["2023-03-01", "2023-03-02", "2023-03-03", "2023-03-04", "2023-03-05"],
// datasets: [{
// x: '2021-11-06 23:39:30',
// y: 50
// }, {
// x: '2021-11-07 01:00:28',
// y: 60
// }, {
// x: '2021-11-07 09:00:28',
// y: 20
// }]
},
// datasets: [{
// data: [103, 589, 537, 543, 574],
// backgroundColor: "rgba(63,500,126,1)",
// hoverBackgroundColor: "rgba(50,90,100,1)"
// }, {
// data: [238, 553, 746, 884, 903],
// backgroundColor: "rgba(163,103,126,1)",
// hoverBackgroundColor: "rgba(140,85,100,1)"
// }, {
// data: [1238, 553, 746, 884, 903],
// backgroundColor: "rgba(63,203,226,1)",
// hoverBackgroundColor: "rgba(46,185,235,1)"
// }],
chartOptions: {
indexAxis: 'y',
scales: {
x: {
// type: 'time',
// time: {
// displayFormats: {
// day: 'MMM D'
// },
// unit: 'day'
// },
stacked: true,
ticks: {
//max: 160,
//min: 10,
//stepSize: 10,
display: false,
// callback: function () {
// return '02:55'
// }
},
},
y: {
stacked: true
},
},
responsive: true,
maintainAspectRatio: false,
aspectRatio: 2,
plugins: {
legend: {
display: true,
labels: {
filter: function (item) {
if (item.text != '')
return item
}
},
},
title: {
display: false,
text: ''
},
tooltip: {
callbacks: {
label: function (context) {
let label = context.dataset.label || '';
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
if (label === "Простой: ") {
label += context.dataset.prostoi_name[context.dataIndex]
} else {
label += context.dataset.date_start[context.dataIndex] + ' - ' + context.dataset.date_end[context.dataIndex]
}
}
return label;
}
}
},
datalabels: {
labels: {
name: {
// anchor: 'end',
align: 'top',
// color: 'black',
display: false,
font: { size: 12 },
formatter: function () {
return 1234
}
},
value: {
color: 'black',
// formatter: function (value, context) {
// return context.dataset.setpoints[0].value + ' / ' + value
// },
// formatter: function (value, context) {
formatter: function (value,) {
return value
},
padding: 2,
// color: function (context) {
// var index = context.dataIndex;
// var value = context.dataset.data[index];
// return value > context.dataset.setpoints[0].value ? 'red' :
// index % 2 ? 'blue' :
// 'green';
// },
}
},
}
}
}
}
},
computed: {
...mapGetters("BOFHeatPhaseAllStatus", {
loading: "loading",
data: "data"
}),
computedDateFormatted() {
let formatDates = [];
formatDates.push(this.formatDate(this.dates[0]));
formatDates.push(this.formatDate(this.dates[1]));
return formatDates.join(" ~ ");
},
},
methods: {
...mapMutations("BOFHeatPhaseAllStatus", {
getExcel: "getExcel",
refreshChart: "refreshChart",
}),
...mapActions("BOFHeatPhaseAllStatus", {
getData: "getData",
}),
Excel() {
this.getExcel([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
},
rowClick: function (item, row) {
let selectState = row.isSelected ? false : true;
row.select(selectState);
},
input(e) {
if (e.length == 2) {
this.datePickerMenu = false;
}
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
refreshData() {
this.chartData.labels = [];
this.chartData.datasets = [];
this.barHeight = 0;
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])])
.then(() => {
this.chartData.labels = this.data.chart.label;
this.chartData.datasets = this.data.chart.dataset;
this.barHeight += (50 * this.data.chart.label.length) + 50
});
},
},
mounted() {
this.refreshData();
}
}
</script>

View File

@@ -0,0 +1,202 @@
<template>
<v-container fluid id="BOFMainUseConfig">
<v-card-text class="text-center headline black--text">Ежесуточный отчет по основным эксплуатационным характеристикам
конверторов АМК
{{ computedDateFormatted }}</v-card-text>
<v-divider class="mx-0"></v-divider>
<v-row>
<v-col style="min-width:250px; max-width:250px;" cols="12">
<v-menu v-model="datePickerMenu" :close-on-content-click="false" :nudge-right="40" :nudge-top="-5"
transition="scale-transition" offset-y min-width="290px">
<template v-slot:activator="{ on }">
<v-text-field id="datePicker" class="datePicker" v-model="computedDateFormatted" prepend-icon="event"
readonly v-on="on" single-line :disabled="loading" />
</template>
<v-date-picker no-title scrollable popover-align="center" v-model="dates"
@input="input($event) && datePickerMenu" @change="refreshData()" range></v-date-picker>
</v-menu>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col style="min-width:180px; max-width:180px;" cols="12">
<v-select v-model="model" :items="items" persistent-hint @change="dataFilter($event)" density="compact"
:disabled="loading" active>
<template v-slot:selection="{ index }">
<span v-if="index === 0">{{ "№ конвертера: " + model + "" }}</span>
</template>
</v-select>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col class="text-center my-4" cols="1" sm="1">
<v-btn :disabled="loading || !data.items.length" tile outlined color="success" @click="loader = Excel()">
<v-icon left size="35">mdi-file-excel</v-icon>Excel
</v-btn>
</v-col>
<v-spacer></v-spacer>
<v-col cols="12" sm="4" md="4" lg="4" xl="3">
<v-text-field v-model="search" append-icon="mdi-magnify" label="Поиск" single-line hide-details clearable
:disabled="loading"></v-text-field>
</v-col>
</v-row>
<v-data-table :headers="headers" :items="data.items" :search="search" item-key="Дата" @click:row="rowClick"
disable-pagination hide-default-footer dense>
>
<template v-slot:top>
<v-progress-linear v-if="loading" indeterminate></v-progress-linear>
</template>
</v-data-table>
</v-container>
</template>
<script>
let jsDate = new Date();
import { mapGetters, mapActions, mapMutations } from "vuex";
export default {
data: () => ({
search: "",
items: [1, 2],
model: 1,
dates: [
new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() - 0)
.toISOString()
.substr(0, 10),
new Date().toISOString().substr(0, 10)
],
datePickerMenu: false
}),
computed: {
...mapGetters("BOFMainUseConfig", {
loading: "loading",
data: "data"
}),
computedDateFormatted() {
let formatDates = [];
formatDates.push(this.formatDate(this.dates[0]));
formatDates.push(this.formatDate(this.dates[1]));
return formatDates.join(" ~ ");
},
headers() {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Roboto, sans-serif";
this.data.headers.forEach(element => {
element.divider = true;
if (element.text == 'Дата') {
element.width = 1000;
}
});
return this.data.headers;
}
},
methods: {
...mapMutations("BOFMainUseConfig", {
getExcel: "getExcel"
}),
...mapActions("BOFMainUseConfig", {
getData: "getData"
}),
dataFilter() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]),
this.model
]);
},
Excel() {
this.getExcel([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]),
this.model
]);
},
rowClick: function (item, row) {
let selectState = row.isSelected ? false : true;
row.select(selectState);
},
input(e) {
if (e.length == 2) {
this.datePickerMenu = false;
}
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
refreshData() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]),
this.model
]);
}
},
mounted() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]),
this.model
]);
}
};
</script>
<style>
.datePicker input {
text-align: center;
cursor: pointer;
}
#BOFMainUseConfig .v-data-table table>tbody>tr>td:nth-child(1),
#BOFMainUseConfig .v-data-table table>thead>tr>th:nth-child(1) {
position: sticky !important;
position: -webkit-sticky !important;
left: 0;
background-color: #fafafa !important;
}
#BOFMainUseConfig .theme--light.v-data-table tbody tr.v-data-table__selected {
background: #f5c17d70 !important;
}
#BOFMainUseConfig .theme--dark.v-data-table tbody tr.v-data-table__selected {
background: #a17b4970 !important;
}
#BOFMainUseConfig .theme--dark.v-data-table tbody tr.v-data-table__selected:hover {
background: #a17b49c2 !important;
}
#BOFMainUseConfig .theme--light.v-data-table tbody tr.v-data-table__selected:hover {
background: #ffd296d2 !important;
}
#BOFMainUseConfig .spacer {
margin-top: 3em;
}
#BOFMainUseConfig .divider {
border-right: rgba(0, 0, 0, 0.12) solid 1px;
}
#BOFMainUseConfig .v-data-table {
border-left: thin solid rgba(0, 0, 0, 0.12);
border-top: thin solid rgba(0, 0, 0, 0.12);
border-bottom: thin solid rgba(0, 0, 0, 0.12);
border-radius: 0;
}
#BOFMainUseConfig .v-data-table table>tbody>tr>td {
border-right: thin solid rgba(0, 0, 0, 0.12);
}
#BOFMainUseConfig #datePicker {
text-align: center;
}
</style>

View File

@@ -0,0 +1,532 @@
<template>
<v-container fluid id="BOFReportAvgData_Marka">
<div class="chart" v-for="(data, index) in allChartData" :key="index">
<Bar class="d-none" :data="data" ref="allBar" :options="allChartOptions[index]" />
</div>
<v-card-text class="text-center headline black--text">Показатели по работе КО (побригадно) за период
{{ computedDateFormatted }}</v-card-text>
<v-divider class="mx-0 elevation-4"></v-divider>
<v-row>
<v-col style="min-width:250px; max-width:250px;" cols="12">
<v-menu v-model="datePickerMenu" :close-on-content-click="false" :nudge-right="40" :nudge-top="-5"
transition="scale-transition" offset-y min-width="290px">
<template v-slot:activator="{ on }">
<v-text-field id="datePicker" class="datePicker" v-model="computedDateFormatted" prepend-icon="event"
readonly v-on="on" single-line :disabled="loading" />
</template>
<v-date-picker no-title scrollable popover-align="center" v-model="dates"
@input="input($event) && datePickerMenu" @change="refreshData()" range></v-date-picker>
</v-menu>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col style="min-width:180px; max-width:180px;" cols="12">
<v-select v-model="BofSelect" :items="listBof" persistent-hint @change="refreshData()" density="compact"
:disabled="loading" active>
<template v-slot:selection="{ index }">
<span v-if="index === 0">{{ "№ конвертера: " + BofSelect + "" }}</span>
</template>
</v-select>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col style="min-width:210px; max-width:210px;" cols="12">
<v-select v-model="CrewSelect" :items="data.crewList" multiple :label=data.label persistent-hint
@change="dataFilter($event)" density="compact" :disabled="loading" active>
<template v-slot:selection="{ index }">
<span v-if="index === 0">{{ "Выбрано бригад: (" + CrewSelect.length + ")" }}</span>
</template>
</v-select>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col style="min-width:300px; max-width:300px;" cols="12">
<v-select v-model="defaultSetpoints" :items="data.itemsSetpoints" item-value="desc" item-text="desc"
@change="chartSetpoints($event)" persistent-hint hide-details active :disabled="loading">
<template v-slot:selection="data">{{ `${data.item.desc}- (${data.item.value})` }}</template>
<template v-slot:item="data">
<div class="overline" v-if="data.item.isHeader">
{{ data.item.desc }}
</div>
<div v-else>
{{ `${data.item.desc} - (${data.item.value})` }}
</div>
</template>
</v-select>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col class="text-center my-4" cols="1" sm="1">
<v-btn tile outlined color="success" :disabled="loading" @click="loader = Excel()">
<v-icon left size="35">mdi-file-excel</v-icon>Excel
</v-btn>
</v-col>
</v-row>
<v-divider class="elevation-0 py-4"></v-divider>
<v-row v-if="data.items.length">
<v-col>
<v-card :width="360" :height="300" outlined tile>
<template>
<div>
<Bar v-if="chartData.datasets.length" :data="chartData" ref="bar" :options="chartOptions" :width="350"
:height="300" />
</div>
</template>
</v-card>
</v-col>
</v-row>
<!-- <v-row>
<v-spacer> </v-spacer>
<v-col cols="12" sm="4" md="4" lg="4" xl="3" style="max-width:300px; min-width:300px;">
<v-text-field v-model="search" append-icon="mdi-magnify" label="Поиск" single-line hide-details clearable
:disabled="loading"></v-text-field>
</v-col>
</v-row> -->
<v-spacer> </v-spacer>
<v-data-table :headers="headers" :items="data.items" :loading="loading" :search="search" dense disable-pagination
hide-default-footer group-by="Бригада" group-expand="true">
<template v-if="data.items.length" v-slot:header :class="header.visibility">
<thead class="grey lighten-5 text-center">
<tr>
<th class="text-center divider d-none d-sm-table-cell" :colspan="8"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5">Чугун</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="8">Материалы</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5">Повалка</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="4">Шлак</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="3">Додувки</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="1"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="23">ОРСС</th>
</tr>
</thead>
</template>
<template v-slot:group.header="{ group, headers, toggle, remove, items, isOpen }">
<th class="text-center divider d-sm-table-cell" :colspan="2">
<td :colspan="headers.length">
<v-btn @click="toggle" small icon :ref="group" :data-open="isOpen">
<v-icon v-if="isOpen">mdi-minus</v-icon>
<v-icon v-else>mdi-plus</v-icon>
</v-btn>
<span class="mx-5 font-weight-bold">{{ `Бригада:${group}` }}</span>
</td>
</th>
<template v-if="group === 1">
<template v-for="(item, index, text) in headers">
<th
v-if="item.text === 'Кол. плавок, шт' || item.text === 'C, шт' || item.text === 'P, шт' || item.text === 'Cr, шт'"
:key="text" class="text-center divider d-sm-table-cell">{{
data.sumDataBrigada1[item.text] }}</th>
<th v-else-if="item.text != 'Дата' && item.text != 'Марка'" :key="text"
class="text-center divider d-sm-table-cell">{{
data.avgDataBrigada1[item.text] }}</th>
</template>
</template>
<template v-if="group === 2">
<template v-for="(item, index, text) in headers">
<th
v-if="item.text === 'Кол. плавок, шт' || item.text === 'C, шт' || item.text === 'P, шт' || item.text === 'Cr, шт'"
:key="text" class="text-center divider d-sm-table-cell">{{
data.sumDataBrigada2[item.text] }}</th>
<th v-else-if="item.text != 'Дата' && item.text != 'Марка'" :key="text"
class="text-center divider d-sm-table-cell">{{
data.avgDataBrigada2[item.text] }}</th>
</template>
</template>
<template v-if="group === 3">
<template v-for="(item, index, text) in headers">
<th
v-if="item.text === 'Кол. плавок, шт' || item.text === 'C, шт' || item.text === 'P, шт' || item.text === 'Cr, шт'"
:key="text" class="text-center divider d-sm-table-cell">{{
data.sumDataBrigada3[item.text] }}</th>
<th v-else-if="item.text != 'Дата' && item.text != 'Марка'" :key="text"
class="text-center divider d-sm-table-cell">{{
data.avgDataBrigada3[item.text] }}</th>
</template>
</template>
<template v-if="group === 4">
<template v-for="(item, index, text) in headers">
<th
v-if="item.text === 'Кол. плавок, шт' || item.text === 'C, шт' || item.text === 'P, шт' || item.text === 'Cr, шт'"
:key="text" class="text-center divider d-sm-table-cell">{{
data.sumDataBrigada4[item.text] }}</th>
<th v-else-if="item.text != 'Дата' && item.text != 'Марка'" :key="text"
class="text-center divider d-sm-table-cell">{{
data.avgDataBrigada4[item.text] }}</th>
</template>
</template>
</template>
</v-data-table>
</v-container>
</template>
<style>
.datePicker input {
text-align: center;
cursor: pointer;
}
</style>
<script>
import { _ } from "vue-underscore";
let jsDate = new Date();
import { mapGetters, mapActions, mapMutations } from "vuex";
import {
Chart as ChartJS,
Title,
Tooltip,
Legend,
BarElement,
CategoryScale,
LinearScale,
} from 'chart.js'
import { Bar } from 'vue-chartjs'
import ChartDataLabels from 'chartjs-plugin-datalabels';
ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend, ChartDataLabels)
//import { nextTick } from 'vue'
export default {
components: {
Bar,
},
data: () => ({
allChartData: [],
chartData: {
labels: [],
datasets: []
},
allChartOptions: [],
chartOptions: {
scale: {
y: {
type: 'linear',
grace: '1%'
},
// min: 0.1,
// max: 150,
// stepSize: 0.0100
// type: 'logarithmic',
//weight: 5
},
responsive: true,
maintainAspectRatio: false,
// maintainAspectRatio: false,
plugins: {
legend: {
display: false
},
title: {
display: true,
text: ''
},
datalabels: {
labels: {
name: {
anchor: 'end',
align: 'top',
color: 'black',
display: false,
font: { size: 12 },
formatter: function (value, context) {
return context.dataset.label
}
},
value: {
color: 'black',
// formatter: function (value, context) {
// return context.dataset.setpoints[0].value + ' / ' + value
// },
display: 'auto',
padding: 2,
// color: function (context) {
// var index = context.dataIndex;
// var value = context.dataset.data[index];
// return value > context.dataset.setpoints[0].value ? 'red' :
// index % 2 ? 'blue' :
// 'green';
// },
}
},
}
}
},
refsArr: [],
search: "",
listBof: [1, 2],
BofSelect: 1,
listCrew: [1, 2, 3, 4],
CrewSelect: [],
defaultSetpoints: "Цикл плавки, мин\r\n",
dates: [
new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() - 0)
.toISOString()
.substr(0, 10),
new Date().toISOString().substr(0, 10)
],
datePickerMenu: false
}),
// watch:{
// 'chartData.datasets'(){
// // console.log(1222)
// this.refsArr.push(this.$refs.bar.$el.toDataURL('image/png'));
// },
// },
// watch: {
// chartData() {
// console.log(1222)
// },
// },
computed: {
...mapGetters("BOFReportAvgData_Marka", {
loading: "loading",
data: "data"
}),
computedDateFormatted() {
let formatDates = [];
formatDates.push(this.formatDate(this.dates[0]));
formatDates.push(this.formatDate(this.dates[1]));
return formatDates.join(" ~ ");
},
groupHeders(h) {
return _.map(h, function (o) { return _.omit(o, 'Марка', 'Дата') })
},
headers() {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Roboto, sans-serif";
this.data.headers.forEach(element => {
var metrics = ctx.measureText(element.text);
var cellWidth = metrics.width;
element.width = cellWidth + 65;
element.align = "center";
element.divider = true;
});
return this.data.headers;
},
headersSetpoints() {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Roboto, sans-serif";
this.data.headersSetpoints.forEach(element => {
var metrics = ctx.measureText(element.text);
var cellWidth = metrics.width;
element.width = cellWidth + 65;
element.align = "center";
element.divider = true;
});
return this.data.headersSetpoints;
}
},
methods: {
...mapActions("BOFReportAvgData_Marka", {
getData: "getData",
refreshChart: "refreshChart",
buildAllChart: "buildAllChart",
}),
...mapMutations("BOFReportAvgData_Marka", {
dataFilter: "dataFilter",
getExcel: "getExcel",
chartSetpoints: "chartSetpoints",
}),
chartSetpoints(select) {
// console.log(select)
this.defaultSetpoints = select;
this.chartOptions.plugins.title.text = select;
this.chartData.datasets = [];
this.refreshChart(select).then(() => {
this.chartData.datasets = this.data.chart.dataset;
this.chartData.labels = this.data.chart.label;
this.chartOptions.plugins.title.text = this.defaultSetpoints + '/ План: ' + this.data.chart.currentPoints;
});
},
xlsCharts() {
return new Promise(resolve => {
this.allChartData = [];
this.allChartOptions = [];
this.buildAllChart(this.data.itemsSetpoints).then(() => {
this.data.allChart.dataset.forEach((item) => {
this.allChartOptions.push({
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false
},
title: {
display: true,
text: item[0].label + '/ План: ' + item[0].setpoints[0].value
},
datalabels: {
labels: {
name: {
anchor: 'end',
align: 'top',
color: 'black',
display: false,
font: { size: 12 },
formatter: function (value, context) {
return context.dataset.label
}
},
value: {
color: 'black',
display: 'auto',
padding: 2,
}
},
}
}
})
this.allChartData.push({ datasets: item, labels: this.data.chart.label });
})
});
resolve();
});
},
Excel() {
let refsArr = [];
this.$refs.allBar.forEach((item,) => {
refsArr.push(item.$el.toDataURL('image/png'));
})
this.getExcel([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]),
this.BofSelect,
refsArr,
]);
},
input(e) {
if (e.length == 2) {
this.datePickerMenu = false;
}
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
refreshData() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]), this.BofSelect])
.then(() => {
this.CrewSelect = this.data.crewList
this.chartData.datasets = [];
this.chartData.labels = [];
this.refreshChart(this.defaultSetpoints).then(() => {
this.chartData.labels = this.data.chart.label;
this.chartData.datasets = this.data.chart.dataset;
this.chartOptions.plugins.title.text = this.defaultSetpoints + '/ План: ' + this.data.chart.currentPoints;
this.xlsCharts();
});
try {
this.closeAll();
} catch (error) {
console.log(error)
}
});
},
closeAll() {
Object.keys(this.$refs).forEach(k => {
if (this.$refs[k] && this.$refs[k].$attrs['data-open']) {
this.$refs[k].$el.click()
}
})
},
},
mounted() {
this.refreshData();
}
};
</script>
<style>
.chart {
max-width: 350px !important;
max-height: 300px !important;
width: 350px;
height: 350px;
position: absolute;
}
.datePicker input {
text-align: center;
cursor: pointer;
}
#BOFReportAvgData_Marka .v-data-table-header {
background-color: #fafafa !important;
}
#BOFReportAvgData_Marka .spacer {
margin-top: 3em;
}
#BOFReportAvgData_Marka .divider {
border-right: rgba(0, 0, 0, 0.12) solid 1px;
}
#BOFReportAvgData_Marka .v-data-table {
border-left: thin solid rgba(0, 0, 0, 0.12);
border-top: thin solid rgba(0, 0, 0, 0.12);
border-bottom: thin solid rgba(0, 0, 0, 0.12);
border-radius: 0;
}
#BOFReportAvgData_Marka .v-data-table table>tbody>tr>td {
border-right: thin solid rgba(0, 0, 0, 0.12);
}
#BOFReportAvgData_Marka #datePicker {
text-align: center;
}
</style>

View File

@@ -0,0 +1,532 @@
<template>
<v-container fluid id="BOFReportAvgData_Marka">
<div class="chart" v-for="(data, index) in allChartData" :key="index">
<Bar class="d-none" :data="data" ref="allBar" :options="allChartOptions[index]" />
</div>
<v-card-text class="text-center headline black--text">Показатели по работе КО (побригадно) за период
{{ computedDateFormatted }}</v-card-text>
<v-divider class="mx-0 elevation-4"></v-divider>
<v-row>
<v-col style="min-width:250px; max-width:250px;" cols="12">
<v-menu v-model="datePickerMenu" :close-on-content-click="false" :nudge-right="40" :nudge-top="-5"
transition="scale-transition" offset-y min-width="290px">
<template v-slot:activator="{ on }">
<v-text-field id="datePicker" class="datePicker" v-model="computedDateFormatted" prepend-icon="event"
readonly v-on="on" single-line :disabled="loading" />
</template>
<v-date-picker no-title scrollable popover-align="center" v-model="dates"
@input="input($event) && datePickerMenu" @change="refreshData()" range></v-date-picker>
</v-menu>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col style="min-width:180px; max-width:180px;" cols="12">
<v-select v-model="BofSelect" :items="listBof" persistent-hint @change="refreshData()" density="compact"
:disabled="loading" active>
<template v-slot:selection="{ index }">
<span v-if="index === 0">{{ "№ конвертера: " + BofSelect + "" }}</span>
</template>
</v-select>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col style="min-width:210px; max-width:210px;" cols="12">
<v-select v-model="CrewSelect" :items="data.crewList" multiple :label=data.label persistent-hint
@change="dataFilter($event)" density="compact" :disabled="loading" active>
<template v-slot:selection="{ index }">
<span v-if="index === 0">{{ "Выбрано бригад: (" + CrewSelect.length + ")" }}</span>
</template>
</v-select>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col style="min-width:300px; max-width:300px;" cols="12">
<v-select v-model="defaultSetpoints" :items="data.itemsSetpoints" item-value="desc" item-text="desc"
@change="chartSetpoints($event)" persistent-hint hide-details active :disabled="loading">
<template v-slot:selection="data">{{ `${data.item.desc}- (${data.item.value})` }}</template>
<template v-slot:item="data">
<div class="overline" v-if="data.item.isHeader">
{{ data.item.desc }}
</div>
<div v-else>
{{ `${data.item.desc} - (${data.item.value})` }}
</div>
</template>
</v-select>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col class="text-center my-4" cols="1" sm="1">
<v-btn tile outlined color="success" :disabled="loading" @click="loader = Excel()">
<v-icon left size="35">mdi-file-excel</v-icon>Excel
</v-btn>
</v-col>
</v-row>
<v-divider class="elevation-0 py-4"></v-divider>
<v-row v-if="data.items.length">
<v-col>
<v-card :width="360" :height="300" outlined tile>
<template>
<div>
<Bar v-if="chartData.datasets.length" :data="chartData" ref="bar" :options="chartOptions" :width="350"
:height="300" />
</div>
</template>
</v-card>
</v-col>
</v-row>
<!-- <v-row>
<v-spacer> </v-spacer>
<v-col cols="12" sm="4" md="4" lg="4" xl="3" style="max-width:300px; min-width:300px;">
<v-text-field v-model="search" append-icon="mdi-magnify" label="Поиск" single-line hide-details clearable
:disabled="loading"></v-text-field>
</v-col>
</v-row> -->
<v-spacer> </v-spacer>
<v-data-table :headers="headers" :items="data.items" :loading="loading" :search="search" dense disable-pagination
hide-default-footer group-by="Бригада" group-expand="true">
<template v-if="data.items.length" v-slot:header :class="header.visibility">
<thead class="grey lighten-5 text-center">
<tr>
<th class="text-center divider d-none d-sm-table-cell" :colspan="8"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5">Чугун</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="8">Материалы</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5">Повалка</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="4">Шлак</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="3">Додувки</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="1"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="23">ОРСС</th>
</tr>
</thead>
</template>
<template v-slot:group.header="{ group, headers, toggle, remove, items, isOpen }">
<th class="text-center divider d-sm-table-cell" :colspan="2">
<td :colspan="headers.length">
<v-btn @click="toggle" small icon :ref="group" :data-open="isOpen">
<v-icon v-if="isOpen">mdi-minus</v-icon>
<v-icon v-else>mdi-plus</v-icon>
</v-btn>
<span class="mx-5 font-weight-bold">{{ `Бригада:${group}` }}</span>
</td>
</th>
<template v-if="group === 1">
<template v-for="(item, index, text) in headers">
<th
v-if="item.text === 'Кол. плавок, шт' || item.text === 'C, шт' || item.text === 'P, шт' || item.text === 'Cr, шт'"
:key="text" class="text-center divider d-sm-table-cell">{{
data.sumDataBrigada1[item.text] }}</th>
<th v-else-if="item.text != 'Дата' && item.text != 'Марка'" :key="text"
class="text-center divider d-sm-table-cell">{{
data.avgDataBrigada1[item.text] }}</th>
</template>
</template>
<template v-if="group === 2">
<template v-for="(item, index, text) in headers">
<th
v-if="item.text === 'Кол. плавок, шт' || item.text === 'C, шт' || item.text === 'P, шт' || item.text === 'Cr, шт'"
:key="text" class="text-center divider d-sm-table-cell">{{
data.sumDataBrigada2[item.text] }}</th>
<th v-else-if="item.text != 'Дата' && item.text != 'Марка'" :key="text"
class="text-center divider d-sm-table-cell">{{
data.avgDataBrigada2[item.text] }}</th>
</template>
</template>
<template v-if="group === 3">
<template v-for="(item, index, text) in headers">
<th
v-if="item.text === 'Кол. плавок, шт' || item.text === 'C, шт' || item.text === 'P, шт' || item.text === 'Cr, шт'"
:key="text" class="text-center divider d-sm-table-cell">{{
data.sumDataBrigada3[item.text] }}</th>
<th v-else-if="item.text != 'Дата' && item.text != 'Марка'" :key="text"
class="text-center divider d-sm-table-cell">{{
data.avgDataBrigada3[item.text] }}</th>
</template>
</template>
<template v-if="group === 4">
<template v-for="(item, index, text) in headers">
<th
v-if="item.text === 'Кол. плавок, шт' || item.text === 'C, шт' || item.text === 'P, шт' || item.text === 'Cr, шт'"
:key="text" class="text-center divider d-sm-table-cell">{{
data.sumDataBrigada4[item.text] }}</th>
<th v-else-if="item.text != 'Дата' && item.text != 'Марка'" :key="text"
class="text-center divider d-sm-table-cell">{{
data.avgDataBrigada4[item.text] }}</th>
</template>
</template>
</template>
</v-data-table>
</v-container>
</template>
<style>
.datePicker input {
text-align: center;
cursor: pointer;
}
</style>
<script>
import { _ } from "vue-underscore";
let jsDate = new Date();
import { mapGetters, mapActions, mapMutations } from "vuex";
import {
Chart as ChartJS,
Title,
Tooltip,
Legend,
BarElement,
CategoryScale,
LinearScale,
} from 'chart.js'
import { Bar } from 'vue-chartjs'
import ChartDataLabels from 'chartjs-plugin-datalabels';
ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend, ChartDataLabels)
//import { nextTick } from 'vue'
export default {
components: {
Bar,
},
data: () => ({
allChartData: [],
chartData: {
labels: [],
datasets: []
},
allChartOptions: [],
chartOptions: {
scale: {
y: {
type: 'linear',
grace: '1%'
},
// min: 0.1,
// max: 150,
// stepSize: 0.0100
// type: 'logarithmic',
//weight: 5
},
responsive: true,
maintainAspectRatio: false,
// maintainAspectRatio: false,
plugins: {
legend: {
display: false
},
title: {
display: true,
text: ''
},
datalabels: {
labels: {
name: {
anchor: 'end',
align: 'top',
color: 'black',
display: false,
font: { size: 12 },
formatter: function (value, context) {
return context.dataset.label
}
},
value: {
color: 'black',
// formatter: function (value, context) {
// return context.dataset.setpoints[0].value + ' / ' + value
// },
display: 'auto',
padding: 2,
// color: function (context) {
// var index = context.dataIndex;
// var value = context.dataset.data[index];
// return value > context.dataset.setpoints[0].value ? 'red' :
// index % 2 ? 'blue' :
// 'green';
// },
}
},
}
}
},
refsArr: [],
search: "",
listBof: [1, 2],
BofSelect: 1,
listCrew: [1, 2, 3, 4],
CrewSelect: [],
defaultSetpoints: "Цикл плавки, мин\r\n",
dates: [
new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() - 0)
.toISOString()
.substr(0, 10),
new Date().toISOString().substr(0, 10)
],
datePickerMenu: false
}),
// watch:{
// 'chartData.datasets'(){
// // console.log(1222)
// this.refsArr.push(this.$refs.bar.$el.toDataURL('image/png'));
// },
// },
// watch: {
// chartData() {
// console.log(1222)
// },
// },
computed: {
...mapGetters("BOFReportAvgData_Marka", {
loading: "loading",
data: "data"
}),
computedDateFormatted() {
let formatDates = [];
formatDates.push(this.formatDate(this.dates[0]));
formatDates.push(this.formatDate(this.dates[1]));
return formatDates.join(" ~ ");
},
groupHeders(h) {
return _.map(h, function (o) { return _.omit(o, 'Марка', 'Дата') })
},
headers() {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Roboto, sans-serif";
this.data.headers.forEach(element => {
var metrics = ctx.measureText(element.text);
var cellWidth = metrics.width;
element.width = cellWidth + 65;
element.align = "center";
element.divider = true;
});
return this.data.headers;
},
headersSetpoints() {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Roboto, sans-serif";
this.data.headersSetpoints.forEach(element => {
var metrics = ctx.measureText(element.text);
var cellWidth = metrics.width;
element.width = cellWidth + 65;
element.align = "center";
element.divider = true;
});
return this.data.headersSetpoints;
}
},
methods: {
...mapActions("BOFReportAvgData_Marka", {
getData: "getData",
refreshChart: "refreshChart",
buildAllChart: "buildAllChart",
}),
...mapMutations("BOFReportAvgData_Marka", {
dataFilter: "dataFilter",
getExcel: "getExcel",
chartSetpoints: "chartSetpoints",
}),
chartSetpoints(select) {
// console.log(select)
this.defaultSetpoints = select;
this.chartOptions.plugins.title.text = select;
this.chartData.datasets = [];
this.refreshChart(select).then(() => {
this.chartData.datasets = this.data.chart.dataset;
this.chartData.labels = this.data.chart.label;
this.chartOptions.plugins.title.text = this.defaultSetpoints + '/ План: ' + this.data.chart.currentPoints;
});
},
xlsCharts() {
return new Promise(resolve => {
this.allChartData = [];
this.allChartOptions = [];
this.buildAllChart(this.data.itemsSetpoints).then(() => {
this.data.allChart.dataset.forEach((item) => {
this.allChartOptions.push({
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false
},
title: {
display: true,
text: item[0].label + '/ План: ' + item[0].setpoints[0].value
},
datalabels: {
labels: {
name: {
anchor: 'end',
align: 'top',
color: 'black',
display: false,
font: { size: 12 },
formatter: function (value, context) {
return context.dataset.label
}
},
value: {
color: 'black',
display: 'auto',
padding: 2,
}
},
}
}
})
this.allChartData.push({ datasets: item, labels: this.data.chart.label });
})
});
resolve();
});
},
Excel() {
let refsArr = [];
this.$refs.allBar.forEach((item,) => {
refsArr.push(item.$el.toDataURL('image/png'));
})
this.getExcel([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]),
this.BofSelect,
refsArr,
]);
},
input(e) {
if (e.length == 2) {
this.datePickerMenu = false;
}
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
refreshData() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]), this.BofSelect])
.then(() => {
this.CrewSelect = this.data.crewList
this.chartData.datasets = [];
this.chartData.labels = [];
this.refreshChart(this.defaultSetpoints).then(() => {
this.chartData.labels = this.data.chart.label;
this.chartData.datasets = this.data.chart.dataset;
this.chartOptions.plugins.title.text = this.defaultSetpoints + '/ План: ' + this.data.chart.currentPoints;
this.xlsCharts();
});
try {
this.closeAll();
} catch (error) {
console.log(error)
}
});
},
closeAll() {
Object.keys(this.$refs).forEach(k => {
if (this.$refs[k] && this.$refs[k].$attrs['data-open']) {
this.$refs[k].$el.click()
}
})
},
},
mounted() {
this.refreshData();
}
};
</script>
<style>
.chart {
max-width: 350px !important;
max-height: 300px !important;
width: 350px;
height: 350px;
position: absolute;
}
.datePicker input {
text-align: center;
cursor: pointer;
}
#BOFReportAvgData_Marka .v-data-table-header {
background-color: #fafafa !important;
}
#BOFReportAvgData_Marka .spacer {
margin-top: 3em;
}
#BOFReportAvgData_Marka .divider {
border-right: rgba(0, 0, 0, 0.12) solid 1px;
}
#BOFReportAvgData_Marka .v-data-table {
border-left: thin solid rgba(0, 0, 0, 0.12);
border-top: thin solid rgba(0, 0, 0, 0.12);
border-bottom: thin solid rgba(0, 0, 0, 0.12);
border-radius: 0;
}
#BOFReportAvgData_Marka .v-data-table table>tbody>tr>td {
border-right: thin solid rgba(0, 0, 0, 0.12);
}
#BOFReportAvgData_Marka #datePicker {
text-align: center;
}
</style>

View File

@@ -0,0 +1,195 @@
<template>
<!-- <v-container fluid id="BOFReport" class="myContainer" style="background-color:rgba(0, 0, 0, 0.43);"> -->
<v-container fluid id="BOFReport">
<v-card-text class="text-center headline black--text">Показатели по работе КО (поплавочно) за период
{{ computedDateFormatted }}</v-card-text>
<v-divider class="mx-0"></v-divider>
<v-row>
<v-col style="min-width:250px; max-width:250px;" cols="12">
<v-menu v-model="datePickerMenu" :close-on-content-click="false" :nudge-right="40" :nudge-top="-5"
transition="scale-transition" offset-y min-width="290px">
<template v-slot:activator="{ on }">
<v-text-field id="datePicker" class="datePicker" v-model="computedDateFormatted" prepend-icon="event"
readonly v-on="on" single-line :disabled="loading" />
</template>
<v-date-picker no-title scrollable popover-align="center" v-model="dates"
@input="input($event) && datePickerMenu" @change="refreshData()" range></v-date-picker>
</v-menu>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col style="min-width:105px; max-width:105px;" cols="12">
<v-select v-model="BofSelect" :items="listBof" @input="dataFilter($event)" hint="№ конвертера" persistent-hint
:disabled="loading" single-line return-object>
<!-- <template v-slot:selection="{ index }">
<span v-if="index === 0">{{ "Выбрано плавок: (" + value.length + ")" }}</span>
</template> -->
</v-select>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col class="text-center my-4" cols="1" sm="1">
<v-btn :disabled="loading || !data.items.length" tile outlined color="success" @click="loader = Excel()">
<v-icon left size="35">mdi-file-excel</v-icon>Excel
</v-btn>
</v-col>
<v-spacer></v-spacer>
<v-col cols="12" sm="4" md="4" lg="4" xl="3">
<v-text-field v-model="search" append-icon="mdi-magnify" label="Поиск" single-line hide-details clearable
:disabled="loading"></v-text-field>
</v-col>
</v-row>
<v-data-table :headers="headers" :items="data.items" :loading="loading" :search="search" dense>
<template v-if="data.items.length" v-slot:header :class="header.visibility">
<thead class="grey lighten-5 text-center">
<tr>
<th class="text-center divider d-none d-sm-table-cell" :colspan="8"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5">Чугун</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="8">Повалка</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5">Повалка</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="4">Шлак</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="3">Додувки</th>
<th class="text-center d-none d-sm-table-cell" :colspan="2"></th>
</tr>
</thead>
</template>
</v-data-table>
</v-container>
</template>
<style>
.datePicker input {
text-align: center;
cursor: pointer;
}
</style>
<script>
//, mapMutations, mapActions
let jsDate = new Date();
import { mapGetters, mapActions, mapMutations } from "vuex";
export default {
data: () => ({
search: "",
BofSelect: 'K1',
listBof: ['K1', 'K2'],
dates: [
new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() - 0)
.toISOString()
.substr(0, 10),
new Date().toISOString().substr(0, 10)
],
datePickerMenu: false
}),
computed: {
...mapGetters("BOFReportSample_A1", {
loading: "loading",
data: "data"
}),
computedDateFormatted() {
let formatDates = [];
formatDates.push(this.formatDate(this.dates[0]));
formatDates.push(this.formatDate(this.dates[1]));
return formatDates.join(" ~ ");
},
headers() {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Roboto, sans-serif";
this.data.headers.forEach(element => {
var metrics = ctx.measureText(element.text);
var cellWidth = metrics.width;
element.width = cellWidth + 65;
element.align = "center";
element.divider = true;
if (element.value === "dateForSort" || element.value === "idGroup") {
element.align = " d-none";
}
});
return this.data.headers;
}
},
methods: {
...mapMutations("BOFReportSample_A1", {
getExcel: "getExcel"
}),
...mapActions("BOFReportSample_A1", {
getData: "getData"
}),
dataFilter() {
this.refreshData();
// switch (this.BofSelect) {
// case 'K1':
// this.getData([
// this.formatDate(this.dates[0]),
// this.formatDate(this.dates[1]), '1'])
// break;
// case 'K2':
// this.getData([
// this.formatDate(this.dates[0]),
// this.formatDate(this.dates[1]), '2'])
// break;
// }
},
input(e) {
if (e.length == 2) {
this.datePickerMenu = false;
}
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
refreshData() {
switch (this.BofSelect) {
case 'K1':
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]), '1'])
break;
case 'K2':
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]), '2'])
break;
}
},
Excel() {
this.getExcel([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]),
this.model
]);
},
},
mounted() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]), '1'])
.then(() => { });
}
};
</script>
<style>
#BOFReport .divider {
border-right: rgba(0, 0, 0, 0.12) solid 1px;
}
#BOFReport .v-data-table {
border: thin solid rgba(0, 0, 0, 0.12);
border-radius: 0;
}
#BOFReport .v-data-table-header {
background-color: #fafafa !important;
}
#BOFReport #datePicker {
text-align: center;
}
</style>

View File

@@ -0,0 +1,193 @@
<template>
<!-- <v-container fluid id="BOFReport" class="myContainer" style="background-color:rgba(0, 0, 0, 0.43);"> -->
<v-container fluid id="BOFReport">
<v-card-text class="text-center headline black--text">Показатели по работе КО (посуточно) за период
{{ computedDateFormatted }}</v-card-text>
<v-divider class="mx-0"></v-divider>
<v-row>
<v-col style="min-width:250px; max-width:250px;" cols="12">
<v-menu v-model="datePickerMenu" :close-on-content-click="false" :nudge-right="40" :nudge-top="-5"
transition="scale-transition" offset-y min-width="290px">
<template v-slot:activator="{ on }">
<v-text-field id="datePicker" class="datePicker" v-model="computedDateFormatted" prepend-icon="event"
readonly v-on="on" single-line :disabled="loading" />
</template>
<v-date-picker no-title scrollable popover-align="center" v-model="dates"
@input="input($event) && datePickerMenu" @change="refreshData()" range></v-date-picker>
</v-menu>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col style="min-width:105px; max-width:105px;" cols="12">
<v-select v-model="BofSelect" :items="listBof" @input="dataFilter($event)" hint="№ конвертера" persistent-hint
:disabled="loading" single-line return-object>
<!-- <template v-slot:selection="{ index }">
<span v-if="index === 0">{{ "Выбрано плавок: (" + value.length + ")" }}</span>
</template> -->
</v-select>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col class="text-center my-4" cols="1" sm="1">
<v-btn :disabled="loading || !data.items.length" tile outlined color="success" @click="loader = Excel()">
<v-icon left size="35">mdi-file-excel</v-icon>Excel
</v-btn>
</v-col>
<v-spacer></v-spacer>
<v-col cols="12" sm="4" md="4" lg="4" xl="3">
<v-text-field v-model="search" append-icon="mdi-magnify" label="Поиск" single-line hide-details clearable
:disabled="loading"></v-text-field>
</v-col>
</v-row>
<v-data-table :headers="headers" :items="data.items" :loading="loading" :search="search" dense>
<template v-if="data.items.length > 1" v-slot:header :class="header.visibility">
<thead class="grey lighten-5 text-center">
<tr>
<th class="text-center divider d-none d-sm-table-cell" :colspan="7"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5">Чугун</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="8">Повалка</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5">Повалка</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="4">Шлак</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="3">Додувки</th>
<th class="text-center d-none d-sm-table-cell" :colspan="5"></th>
</tr>
</thead>
</template>
</v-data-table>
</v-container>
</template>
<style>
.datePicker input {
text-align: center;
cursor: pointer;
}
</style>
<script>
//, mapMutations, mapActions
let jsDate = new Date();
import { mapGetters, mapActions, mapMutations } from "vuex";
export default {
data: () => ({
search: "",
BofSelect: 'K1',
listBof: ['K1', 'K2'],
dates: [
new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() - 0)
.toISOString()
.substr(0, 10),
new Date().toISOString().substr(0, 10)
],
datePickerMenu: false
}),
computed: {
...mapGetters("BOFReportSample_A2", {
loading: "loading",
data: "data"
}),
computedDateFormatted() {
let formatDates = [];
formatDates.push(this.formatDate(this.dates[0]));
formatDates.push(this.formatDate(this.dates[1]));
return formatDates.join(" ~ ");
},
headers() {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Roboto, sans-serif";
this.data.headers.forEach(element => {
var metrics = ctx.measureText(element.text);
var cellWidth = metrics.width;
element.width = cellWidth + 65;
element.align = "center";
element.divider = true;
if (element.value === "dateForSort" || element.value === "idGroup") {
element.align = " d-none";
}
});
return this.data.headers;
}
},
methods: {
...mapMutations("BOFReportSample_A2", {
getExcel: "getExcel"
}),
...mapActions("BOFReportSample_A2", {
getData: "getData"
}),
dataFilter() {
this.refreshData();
// switch (this.BofSelect) {
// case 'K1':
// this.getData([
// this.formatDate(this.dates[0]),
// this.formatDate(this.dates[1]), '1'])
// break;
// case 'K2':
// this.getData([
// this.formatDate(this.dates[0]),
// this.formatDate(this.dates[1]), '2'])
// break;
// }
},
input(e) {
if (e.length == 2) {
this.datePickerMenu = false;
}
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
refreshData() {
switch (this.BofSelect) {
case 'K1':
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]), '1'])
break;
case 'K2':
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]), '2'])
break;
}
},
Excel() {
this.getExcel([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]),
this.model
]);
},
},
mounted() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]), '1'])
.then(() => { });
}
};
</script>
<style>
#BOFReport .divider {
border-right: rgba(0, 0, 0, 0.12) solid 1px;
}
#BOFReport .v-data-table {
border: thin solid rgba(0, 0, 0, 0.12);
border-radius: 0;
}
#BOFReport .v-data-table-header {
background-color: #fafafa !important;
}
#BOFReport #datePicker {
text-align: center;
}
</style>

View File

@@ -0,0 +1,168 @@
<template>
<!-- <v-container fluid id="BOFReport" class="myContainer" style="background-color:rgba(0, 0, 0, 0.43);"> -->
<v-container fluid id="BOFReport">
<v-card-text class="text-center headline black--text">Показатели по работе ККЦ за период
{{ computedDateFormatted }}</v-card-text>
<v-divider class="mx-0"></v-divider>
<v-row>
<v-col style="min-width:250px; max-width:250px;" cols="12">
<v-menu v-model="datePickerMenu" :close-on-content-click="false" :nudge-right="40" :nudge-top="-5"
transition="scale-transition" offset-y min-width="290px">
<template v-slot:activator="{ on }">
<v-text-field id="datePicker" class="datePicker" v-model="computedDateFormatted" prepend-icon="event"
readonly v-on="on" single-line :disabled="loading" />
</template>
<v-date-picker no-title scrollable popover-align="center" v-model="dates"
@input="input($event) && datePickerMenu" @change="refreshData()" range></v-date-picker>
</v-menu>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col class="text-center my-4" cols="1" sm="1">
<v-btn :disabled="loading || !data.items.length" tile outlined color="success" @click="loader = Excel()">
<v-icon left size="35">mdi-file-excel</v-icon>Excel
</v-btn>
</v-col>
<v-spacer></v-spacer>
<v-col cols="12" sm="4" md="4" lg="4" xl="3">
<v-text-field v-model="search" append-icon="mdi-magnify" label="Поиск" single-line hide-details clearable
:disabled="loading"></v-text-field>
</v-col>
</v-row>
<v-data-table :headers="headers" :items="data.items" :loading="loading" :search="search" dense>
<template v-if="data.items.length" v-slot:header :class="header.visibility">
<thead class="grey lighten-5 text-center">
<tr>
<th class="text-center divider d-none d-sm-table-cell" :colspan="4"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="6">Чугун</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5">Шлак конвертерный</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="1"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5">Химический состав УКП - первая проба
</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5">Химический состав УКП - последняя проба
</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="2"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="8">Конвертер</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="4"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="8">Первый шлак УКП</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="8">Последний шлак УКП</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="7"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="11">УКП, кг</th>
</tr>
</thead>
</template>
</v-data-table>
</v-container>
</template>
<style>
.datePicker input {
text-align: center;
cursor: pointer;
}
</style>
<script>
//, mapMutations, mapActions
let jsDate = new Date();
import { mapGetters, mapActions, mapMutations } from "vuex";
export default {
data: () => ({
search: "",
dates: [
new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() - 0)
.toISOString()
.substr(0, 10),
new Date().toISOString().substr(0, 10)
],
datePickerMenu: false
}),
computed: {
...mapGetters("BOFReportSample_B1", {
loading: "loading",
data: "data"
}),
computedDateFormatted() {
let formatDates = [];
formatDates.push(this.formatDate(this.dates[0]));
formatDates.push(this.formatDate(this.dates[1]));
return formatDates.join(" ~ ");
},
headers() {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Roboto, sans-serif";
this.data.headers.forEach(element => {
var metrics = ctx.measureText(element.text);
var cellWidth = metrics.width;
element.width = cellWidth + 65;
element.align = "center";
element.divider = true;
if (element.value === "heatNumber") {
element.align = " d-none";
}
});
return this.data.headers;
}
},
methods: {
...mapMutations("BOFReportSample_B1", {
getExcel: "getExcel"
}),
...mapActions("BOFReportSample_B1", {
getData: "getData"
}),
input(e) {
if (e.length == 2) {
this.datePickerMenu = false;
}
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
refreshData() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
},
Excel() {
this.getExcel([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]),
this.model
]);
},
},
mounted() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
}
};
</script>
<style>
#BOFReport .divider {
border-right: rgba(0, 0, 0, 0.12) solid 1px;
}
#BOFReport .v-data-table {
border: thin solid rgba(0, 0, 0, 0.12);
border-radius: 0;
}
#BOFReport .v-data-table-header {
background-color: #fafafa !important;
}
#BOFReport #datePicker {
text-align: center;
}
</style>

View File

@@ -0,0 +1,190 @@
<template>
<!-- <v-container fluid id="BOFReport" class="myContainer" style="background-color:rgba(0, 0, 0, 0.43);"> -->
<v-container fluid id="BOFReport">
<v-card-text class="text-center headline black--text">Показатели по работе конвертеров за период
{{ computedDateFormatted }}</v-card-text>
<v-divider class="mx-0"></v-divider>
<v-row>
<v-col style="min-width:250px; max-width:250px;" cols="12">
<v-menu v-model="datePickerMenu" :close-on-content-click="false" :nudge-right="40" :nudge-top="-5"
transition="scale-transition" offset-y min-width="290px">
<template v-slot:activator="{ on }">
<v-text-field id="datePicker" class="datePicker" v-model="computedDateFormatted" prepend-icon="event"
readonly v-on="on" single-line :disabled="loading" />
</template>
<v-date-picker no-title scrollable popover-align="center" v-model="dates"
@input="input($event) && datePickerMenu" @change="refreshData()" range></v-date-picker>
</v-menu>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col class="text-center my-4" cols="1" sm="1">
<v-btn :disabled="loading || !data.items.length" tile outlined color="success" @click="loader = Excel()">
<v-icon left size="35">mdi-file-excel</v-icon>Excel
</v-btn>
</v-col>
<v-spacer></v-spacer>
<v-col cols="12" sm="4" md="4" lg="4" xl="3">
<v-text-field v-model="search" append-icon="mdi-magnify" label="Поиск" single-line hide-details clearable
:disabled="loading"></v-text-field>
</v-col>
</v-row>
<v-data-table :headers="headers" :items="data.items" :loading="loading" :search="search" dense>
<template v-if="data.items.length" v-slot:header :class="header.visibility">
<thead class="grey lighten-5 text-center">
<tr>
<th class="text-center divider d-sm-table-cell" :colspan="86">Конвертер</th>
<th class="text-center divider d-sm-table-cell" :colspan="37">УКП</th>
<th class="text-center divider d-sm-table-cell" :colspan="19">УВК</th>
<th class="text-center d-sm-table-cell" :colspan="25">ОРСС</th>
</tr>
</thead>
<thead class="grey lighten-5 text-center">
<tr>
<th class="text-center divider d-none d-sm-table-cell" :colspan="39"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="6">Чугун</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="2">Обработка Чугуна</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="9">Периоды плавки</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="7">Плавка</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5">Повалка</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5">Шлак</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="3">Додувки</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="1"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="6">Химичевский состав УВОС</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="3">Расход газа на плавку</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="4">Данные по ковшу</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="10">Химический состав УКП - первая проба
</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="10">Химический состав УКП - последняя проба
</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="8">Химический состав шлака</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="9"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5">Химический состав УВК - первая проба
</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5">Химический состав УВК - последняя проба
</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5">Химический состав ОРСС</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="7"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="3">Стрипперован</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="7"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="2">Налито годного</th>
<th class="text-center d-none d-sm-table-cell" :colspan="1"></th>
</tr>
</thead>
</template>
</v-data-table>
</v-container>
</template>
<style>
.datePicker input {
text-align: center;
cursor: pointer;
}
</style>
<script>
//, mapMutations, mapActions
let jsDate = new Date();
import { mapGetters, mapActions, mapMutations } from "vuex";
export default {
data: () => ({
search: "",
dates: [
new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() - 0)
.toISOString()
.substr(0, 10),
new Date().toISOString().substr(0, 10)
],
datePickerMenu: false
}),
computed: {
...mapGetters("BOFReportSample_C1", {
loading: "loading",
data: "data"
}),
computedDateFormatted() {
let formatDates = [];
formatDates.push(this.formatDate(this.dates[0]));
formatDates.push(this.formatDate(this.dates[1]));
return formatDates.join(" ~ ");
},
headers() {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Roboto, sans-serif";
this.data.headers.forEach(element => {
var metrics = ctx.measureText(element.text);
var cellWidth = metrics.width;
element.width = cellWidth + 65;
element.align = "center";
element.divider = true;
if (element.value === "sortNumber") {
element.align = " d-none";
}
});
return this.data.headers;
}
},
methods: {
...mapMutations("BOFReportSample_C1", {
getExcel: "getExcel"
}),
...mapActions("BOFReportSample_C1", {
getData: "getData"
}),
input(e) {
if (e.length == 2) {
this.datePickerMenu = false;
}
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
refreshData() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
},
Excel() {
this.getExcel([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1]),
this.model
]);
},
},
mounted() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
}
};
</script>
<style>
#BOFReport .divider {
border-right: rgba(0, 0, 0, 0.12) solid 1px;
}
#BOFReport .v-data-table {
border: thin solid rgba(0, 0, 0, 0.12);
border-radius: 0;
}
#BOFReport .v-data-table-header {
background-color: #fafafa !important;
}
#BOFReport #datePicker {
text-align: center;
}
</style>

View File

@@ -0,0 +1,269 @@
<template>
<!-- <v-container fluid id="BOFReport" class="myContainer" style="background-color:rgba(0, 0, 0, 0.43);"> -->
<v-container fluid id="BOFReport">
<v-card-text
class="text-center headline black--text"
>Анализ передутых плавок за период {{computedDateFormatted}}</v-card-text>
<v-divider class="mx-0"></v-divider>
<v-row>
<v-col style="min-width:250px; max-width:250px;" cols="12">
<v-menu
v-model="datePickerMenu"
:close-on-content-click="false"
:nudge-right="40"
:nudge-top="-5"
transition="scale-transition"
offset-y
min-width="290px"
>
<template v-slot:activator="{ on }">
<v-text-field
id="datePicker"
class="datePicker"
v-model="computedDateFormatted"
prepend-icon="event"
readonly
v-on="on"
single-line
:disabled="loading"
/>
</template>
<v-date-picker
no-title
scrollable
popover-align="center"
v-model="dates"
@input="input($event) && datePickerMenu"
@change="refreshData()"
range
></v-date-picker>
</v-menu>
</v-col>
<v-spacer></v-spacer>
<v-col cols="12" sm="4" md="4" lg="4" xl="3">
<v-text-field
v-model="search"
append-icon="mdi-magnify"
label="Поиск"
single-line
hide-details
clearable
:disabled="loading"
></v-text-field>
</v-col>
</v-row>
<v-row justify="center">
{{`Кол-во передутых плавок составило - ${data.countHeats.HeatsCheckedCount}
(${data.countHeats.PercentChecked}% от общего кол-ва)`}}
</v-row>
<v-row justify="center">
<v-col cols="auto">
<v-card outlined tile max-width="250" :loading="loading">
<v-card-title class="subtitle-1 pb-0">Плавок:</v-card-title>
<v-card-text class="caption py-1">
<span class="text--primary">
{{`Т чуг. меньше 1320ºС - ${data.sampleCounts.TIronLessCount}
(${data.sampleCounts.TIronLessPercent}%)`}}
</span>
</v-card-text>
<v-card-text class="caption py-1">
<span class="text--primary">
{{`Si чуг. меньше 0,4% - ${data.sampleCounts.hm_SiLessCount}
(${data.sampleCounts.hm_SiLessPercent}%)`}}
</span>
</v-card-text>
<v-card-text class="caption py-1">
<span class="text--primary">
{{`Лом больше 65тн. - ${data.sampleCounts.ScrapAnymoreCount}
(${data.sampleCounts.ScrapAnymorePercent}%)`}}
</span>
</v-card-text>
<v-card-text class="caption py-1">
<span class="text--primary">
{{`Si чуг. больше >0,9% - ${data.sampleCounts.hm_SiAnymoreCount}
(${data.sampleCounts.hm_SiAnymorePercent}%)`}}
</span>
</v-card-text>
</v-card>
</v-col>
<v-col cols="auto">
<v-card outlined tile max-width="250" :loading="loading">
<v-card-title class="subtitle-1 pb-0">Мастера:</v-card-title>
<v-card-text class="caption py-1" v-for="(item, i) in data.master" :key="i">
<span class="text--primary">{{`${item.BOFMaster} - ${item.Count} (${item.Percent}%)`}}</span>
</v-card-text>
</v-card>
</v-col>
<v-col cols="auto">
<v-card outlined tile max-width="250" :loading="loading">
<v-card-title class="subtitle-1 pb-0">Маш. дистрибутора 8р.:</v-card-title>
<v-card-text class="caption py-1" v-for="(item, i) in data.operator" :key="i">
<span class="text--primary">{{`${item.BOFOperator} - ${item.Count} (${item.Percent}%)`}}</span>
</v-card-text>
</v-card>
</v-col>
<v-col cols="auto">
<v-card outlined tile max-width="250" :loading="loading">
<v-card-title class="subtitle-1 pb-0">Бригада:</v-card-title>
<v-card-text class="caption py-1" v-for="(item, i) in data.shift" :key="i">
<span
class="text--primary"
>{{`${item.ShiftTeamNo} - ${item.Count} (${item.Percent}%)`}}</span>
</v-card-text>
</v-card>
</v-col>
</v-row>
<v-data-table
class="mt-5"
:headers="headers"
:items="data.items"
:loading="loading"
:search="search"
group-by="Date"
item-key="bofhr_id"
@click:row="rowClick"
dense
>
<template slot="body.append">
<tr v-if="data.items.length" class="pink--text">
<th class="text-center divider d-sm-table-cell" :colspan="2">Cредние значения:</th>
<th class="text-center divider d-sm-table-cell">{{data.avgData.avg_cycle}}</th>
<th class="text-center divider d-sm-table-cell">{{data.avgData.avg_c_pov}}</th>
<th class="text-center divider d-sm-table-cell"></th>
<th class="text-center divider d-sm-table-cell">{{data.avgData.avg_FerroCount}}</th>
<th class="text-center divider d-sm-table-cell">{{data.avgData.avg_t_pov}}</th>
<th class="text-center divider d-sm-table-cell">{{data.avgData.avg_FeOShlag}}</th>
<th class="text-center divider d-sm-table-cell">{{data.avgData.avg_CaOPolysiusHeat}}</th>
<th class="text-center divider d-sm-table-cell">{{data.avgData.avg_CaODolomitedHeat}}</th>
<th class="text-center divider d-sm-table-cell">{{data.avgData.avg_CaCO3Common}}</th>
<th class="text-center divider d-sm-table-cell">{{data.avgData.avg_Coal}}</th>
<th class="text-center divider d-sm-table-cell">{{data.avgData.avg_Scrap}}</th>
<th class="text-center divider d-sm-table-cell">{{data.avgData.avg_HM_WEIGHT}}</th>
<th class="text-center divider d-sm-table-cell">{{data.avgData.avg_hm_t}}</th>
<th class="text-center divider d-sm-table-cell">{{data.avgData.avg_hm_si}}</th>
</tr>
</template>
</v-data-table>
</v-container>
</template>
<style>
.datePicker input {
text-align: center;
cursor: pointer;
}
</style>
<script>
//, mapMutations, mapActions
let jsDate = new Date();
import { mapGetters, mapActions } from "vuex";
export default {
data: () => ({
search: "",
dates: [
new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() - 0)
.toISOString()
.substr(0, 10),
new Date().toISOString().substr(0, 10)
],
datePickerMenu: false
}),
computed: {
...mapGetters("BOFReportSample_D1", {
loading: "loading",
data: "data"
}),
computedDateFormatted() {
let formatDates = [];
formatDates.push(this.formatDate(this.dates[0]));
formatDates.push(this.formatDate(this.dates[1]));
return formatDates.join(" ~ ");
},
headers() {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Roboto, sans-serif";
this.data.headers.forEach(element => {
var metrics = ctx.measureText(element.text);
var cellWidth = metrics.width;
element.width = cellWidth + 65;
element.align = "center";
element.divider = true;
if (element.value === "bofhr_id") {
element.align = " d-none";
}
});
return this.data.headers;
}
},
methods: {
...mapActions("BOFReportSample_D1", {
getData: "getData"
}),
rowClick: function(item, row) {
let selectState = row.isSelected ? false : true;
row.select(selectState);
},
input(e) {
if (e.length == 2) {
this.datePickerMenu = false;
}
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
refreshData() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
}
},
mounted() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
}
};
</script>
<style>
#BOFReport .divider {
border-right: rgba(0, 0, 0, 0.12) solid 1px;
}
#BOFReport .v-data-table {
border: thin solid rgba(0, 0, 0, 0.12);
border-radius: 0;
}
#BOFReport .v-data-table-header {
background-color: #fafafa !important;
}
#BOFReport #datePicker {
text-align: center;
}
.theme--light.v-data-table tbody tr.v-data-table__selected {
background: #f5c17d70 !important;
}
.theme--dark.v-data-table tbody tr.v-data-table__selected {
background: #a17b4970 !important;
}
.theme--dark.v-data-table tbody tr.v-data-table__selected:hover {
background: #a17b49c2 !important;
}
.theme--light.v-data-table tbody tr.v-data-table__selected:hover {
background: #ffd296d2 !important;
}
.spacer {
margin-top: 3em;
}
</style>

View File

@@ -0,0 +1,235 @@
<template>
<v-container fluid id="HMCarReport">
<v-card-text class="text-center headline black--text">Баланс чугуна (поплавочно) за период
{{ computedDateFormatted }}</v-card-text>
<v-divider class="mx-0"></v-divider>
<v-row>
<v-col style="min-width:250px; max-width:250px;" cols="12">
<v-menu v-model="datePickerMenu" :close-on-content-click="false" :nudge-right="40" :nudge-top="-5"
transition="scale-transition" offset-y min-width="290px">
<template v-slot:activator="{ on }">
<v-text-field id="datePicker" class="datePicker" v-model="computedDateFormatted" prepend-icon="event"
readonly v-on="on" single-line :disabled="loading" />
</template>
<v-date-picker no-title scrollable popover-align="center" v-model="dates"
@input="input($event) && datePickerMenu" @change="refreshData()" range></v-date-picker>
</v-menu>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col style="min-width:250px; max-width:250px;" cols="12">
<v-select v-model="value" :items="data.listHeatNumber" label="Номера плавок" multiple persistent-hint
@change="dataFilter($event)" density="compact" :disabled="loading" active>
<template v-slot:selection="{ index }">
<span v-if="index === 0">{{ "Выбрано плавок: (" + value.length + ")" }}</span>
</template>
</v-select>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col class="text-center my-4" cols="1" sm="1">
<v-btn :disabled="loading || !value.length" tile outlined color="success" @click="loader = Excel()">
<v-icon left size="35">mdi-file-excel</v-icon>Excel
</v-btn>
</v-col>
<v-spacer></v-spacer>
<v-col cols="12" sm="3" md="3" lg="3" xl="3">
<v-text-field v-model="search" append-icon="mdi-magnify" label="Поиск" single-line hide-details clearable
:disabled="loading"></v-text-field>
</v-col>
</v-row>
<v-data-table item-key="Номер плавки ККЦ" :headers="headers" :items="data.items" @click:row="rowClick"
:loading="loading" :search="search" disable-pagination hide-default-footer dense>
<template slot="body.append">
<tr v-if="data.items.length" class="pink--text">
<th class="text-center divider d-sm-table-cell" :colspan="4">Сумма:</th>
<th class="text-center divider d-sm-table-cell">{{ data.sumData["Тара, т"] }}</th>
<th class="text-center divider d-sm-table-cell">{{ data.sumData["Брутто, т"] }}</th>
<th class="text-center divider d-sm-table-cell">{{ data.sumData["Нетто, т"] }}</th>
<th class="text-center divider d-sm-table-cell">{{ data.sumData["Вес со снятием, т"] }}</th>
<th class="text-center divider d-sm-table-cell"></th>
<th class="text-center divider d-sm-table-cell">{{ data.sumData["Тара, т "] }}</th>
<th class="text-center divider d-sm-table-cell">{{ data.sumData["Брутто, т "] }}</th>
<th class="text-center divider d-sm-table-cell">{{ data.sumData["Нетто, т "] }}</th>
<th class="text-center divider d-sm-table-cell">{{ data.sumData["Снятие на десульфурации, т"] }}</th>
</tr>
</template>
<template slot="body.append">
<tr v-if="data.items.length" class="pink--text">
<th class="text-center divider d-sm-table-cell" :colspan="4">Среднее:</th>
<th class="text-center divider d-sm-table-cell">{{ data.avgData["Тара, т"] }}</th>
<th class="text-center divider d-sm-table-cell">{{ data.avgData["Брутто, т"] }}</th>
<th class="text-center divider d-sm-table-cell">{{ data.avgData["Нетто, т"] }}</th>
<th class="text-center divider d-sm-table-cell">{{ data.avgData["Вес со снятием, т"] }}</th>
<th class="text-center divider d-sm-table-cell"></th>
<th class="text-center divider d-sm-table-cell">{{ data.avgData["Тара, т "] }}</th>
<th class="text-center divider d-sm-table-cell">{{ data.avgData["Брутто, т "] }}</th>
<th class="text-center divider d-sm-table-cell">{{ data.avgData["Нетто, т "] }}</th>
<th class="text-center divider d-sm-table-cell">{{ data.avgData["Снятие на десульфурации, т"] }}</th>
</tr>
</template>
<template v-if="data.items.length" v-slot:header :class="header.visibility">
<thead class="grey lighten-5 text-center">
<tr>
<th class="text-center divider d-none d-sm-table-cell" :colspan="4"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="5">Вес чугуна на чугуновозе</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="3">Вес чугуна на кране</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="2"></th>
</tr>
</thead>
</template>
</v-data-table>
</v-container>
</template>
<style>
.datePicker input {
text-align: center;
cursor: pointer;
}
</style>
<script>
//, mapMutations, mapActions
let jsDate = new Date();
import { mapGetters, mapActions, mapMutations } from "vuex";
export default {
data: () => ({
value: [],
search: "",
dates: [
new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() - 0)
.toISOString()
.substr(0, 10),
new Date().toISOString().substr(0, 10)
],
datePickerMenu: false
}),
computed: {
...mapGetters("HMCarReport", {
loading: "loading",
data: "data"
}),
computedDateFormatted() {
let formatDates = [];
formatDates.push(this.formatDate(this.dates[0]));
formatDates.push(this.formatDate(this.dates[1]));
return formatDates.join(" ~ ");
},
headers() {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Roboto, sans-serif";
this.data.headers.forEach(element => {
element.align = "center";
element.divider = true;
if (element.value === "HEAT_START") {
element.align = " d-none";
}
});
return this.data.headers;
}
},
methods: {
...mapActions("HMCarReport", {
getData: "getData",
selectHeat: "selectHeat"
}),
...mapMutations("HMCarReport", {
dataFilter: "dataFilter",
getExcel: "getExcel"
}),
Excel() {
this.getExcel([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
},
rowClick: function (item, row) {
let selectState = row.isSelected ? false : true;
row.select(selectState);
},
input(e) {
if (e.length == 2) {
this.datePickerMenu = false;
}
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
refreshData() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]).then(() => {
this.value = this.data.listHeatNumber;
});
}
},
mounted() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]).then(() => {
this.value = this.data.listHeatNumber;
});
}
};
</script>
<style>
#HMCarReport .v-data-table-header {
background-color: #fafafa !important;
}
#HMCarReport .spacer {
margin-top: 3em;
}
#HMCarReport .divider {
border-right: rgba(0, 0, 0, 0.12) solid 1px;
}
#HMCarReport .v-data-table {
border-left: thin solid rgba(0, 0, 0, 0.12);
border-top: thin solid rgba(0, 0, 0, 0.12);
border-bottom: thin solid rgba(0, 0, 0, 0.12);
border-radius: 0;
}
#HMCarReport .v-data-table table>tbody>tr>td {
border-right: thin solid rgba(0, 0, 0, 0.12);
}
.theme--light.v-data-table tbody tr.v-data-table__selected {
background: #f5c17d70 !important;
}
.theme--dark.v-data-table tbody tr.v-data-table__selected {
background: #a17b4970 !important;
}
.theme--dark.v-data-table tbody tr.v-data-table__selected:hover {
background: #a17b49c2 !important;
}
.theme--light.v-data-table tbody tr.v-data-table__selected:hover {
background: #ffd296d2 !important;
}
.spacer {
margin-top: 3em;
}
</style>

183
src/components/HM_DC.vue Normal file
View File

@@ -0,0 +1,183 @@
<template>
<v-container fluid id="HM_DC">
<v-card-text class="text-center headline black--text">Баланс чугуна (Доменный цех) за период
{{ computedDateFormatted }}</v-card-text>
<v-divider class="mx-0"></v-divider>
<v-row>
<v-col style="min-width:250px; max-width:250px;" cols="12">
<v-menu v-model="datePickerMenu" :close-on-content-click="false" :nudge-right="40" :nudge-top="-5"
transition="scale-transition" offset-y min-width="290px">
<template v-slot:activator="{ on }">
<v-text-field id="datePicker" class="datePicker" v-model="computedDateFormatted" prepend-icon="event"
readonly v-on="on" single-line :disabled="loading" />
</template>
<v-date-picker no-title scrollable popover-align="center" v-model="dates"
@input="input($event) && datePickerMenu" @change="refreshData()" range></v-date-picker>
</v-menu>
</v-col>
<v-spacer></v-spacer>
<v-col cols="12" sm="2" md="2" lg="2" xl="2">
<v-text-field v-model="search" append-icon="mdi-magnify" label="Поиск" single-line hide-details clearable
:disabled="loading"></v-text-field>
</v-col>
</v-row>
<v-data-table item-key="id" :headers="headers" :items="data.items" :loading="loading" :search="search"
@click:row="rowClick" disable-pagination hide-default-footer dense>
<template slot="body.append">
<tr v-if="data.items.length" class="font-weight-bold">
<th class="text-right divider d-sm-table-cell" :colspan="6">Сумма:</th>
<th class="text-center divider d-sm-table-cell">{{ data.sumData["Вес"] }}</th>
<th class="text-center divider d-sm-table-cell" :colspan="12"></th>
</tr>
</template>
<template slot="body.append">
<tr v-if="data.items.length" class="font-weight-bold">
<th class="text-right divider d-sm-table-cell" :colspan="6">Среднее:</th>
<th class="text-center divider d-sm-table-cell">{{ data.avgData["Вес"] }}</th>
<th class="text-center divider d-sm-table-cell" :colspan="12"></th>
</tr>
</template>
</v-data-table>
</v-container>
</template>
<style>
.datePicker input {
text-align: center;
cursor: pointer;
}
</style>
<script>
let jsDate = new Date();
import { mapGetters, mapActions, } from "vuex";
export default {
data: () => ({
value: [],
search: "",
dates: [
new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() + 1)
.toISOString()
.substr(0, 10),
new Date().toISOString().substr(0, 10)
],
datePickerMenu: false
}),
computed: {
...mapGetters("HM_DC", {
loading: "loading",
data: "data"
}),
computedDateFormatted() {
let formatDates = [];
formatDates.push(this.formatDate(this.dates[0]));
formatDates.push(this.formatDate(this.dates[1]));
return formatDates.join(" ~ ");
},
headers() {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Roboto, sans-serif";
this.data.headers.forEach(element => {
var metrics = ctx.measureText(element.text);
var cellWidth = metrics.width;
element.width = cellWidth + 65;
element.align = "center";
element.divider = true;
if (element.value === "id") {
element.align = " d-none";
}
});
return this.data.headers;
}
},
methods: {
...mapActions("HM_DC", {
getData: "getData",
}),
rowClick: function (item, row) {
let selectState = row.isSelected ? false : true;
row.select(selectState);
},
input(e) {
if (e.length == 2) {
this.datePickerMenu = false;
}
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
refreshData() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
}
},
mounted() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
}
};
</script>
<style>
.datePicker input {
text-align: center;
cursor: pointer;
}
#HM_DC .v-data-table-header {
background-color: #fafafa !important;
}
#HM_DC .spacer {
margin-top: 3em;
}
#HM_DC .divider {
border-right: rgba(0, 0, 0, 0.12) solid 1px;
}
#HM_DC .v-data-table {
border-left: thin solid rgba(0, 0, 0, 0.12);
border-top: thin solid rgba(0, 0, 0, 0.12);
border-bottom: thin solid rgba(0, 0, 0, 0.12);
border-radius: 0;
}
#HM_DC .v-data-table table>tbody>tr>td {
border-right: thin solid rgba(0, 0, 0, 0.12);
}
#HM_DC #datePicker {
text-align: center;
}
.theme--light.v-data-table tbody tr.v-data-table__selected {
background: #f5c17d70 !important;
}
.theme--dark.v-data-table tbody tr.v-data-table__selected {
background: #a17b4970 !important;
}
.theme--dark.v-data-table tbody tr.v-data-table__selected:hover {
background: #a17b49c2 !important;
}
.theme--light.v-data-table tbody tr.v-data-table__selected:hover {
background: #ffd296d2 !important;
}
</style>

200
src/components/LadleUse.vue Normal file
View File

@@ -0,0 +1,200 @@
<template>
<!-- <v-container fluid id="BOFReport" class="myContainer" style="background-color:rgba(0, 0, 0, 0.43);"> -->
<v-container id="ladleUse">
<v-card-text
class="text-center headline black--text"
>Данные по эксплуатации стальковшей за период {{computedDateFormatted}}</v-card-text>
<v-divider class="mx-0"></v-divider>
<v-row>
<v-col style="min-width:250px; max-width:250px;" cols="12">
<v-menu
v-model="datePickerMenu"
:close-on-content-click="false"
:nudge-right="40"
:nudge-top="-5"
transition="scale-transition"
offset-y
min-width="290px"
>
<template v-slot:activator="{ on }">
<v-text-field
id="datePicker"
class="datePicker"
v-model="computedDateFormatted"
prepend-icon="event"
readonly
v-on="on"
single-line
:disabled="loading"
/>
</template>
<v-date-picker
no-title
scrollable
popover-align="center"
v-model="dates"
@input="input($event) && datePickerMenu"
@change="refreshData()"
range
></v-date-picker>
</v-menu>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col class="text-center my-4" cols="1" sm="1">
<v-btn :disabled="loading" tile outlined color="success" @click="loader = Excel()">
<v-icon left size="35">mdi-file-excel</v-icon>Excel
</v-btn>
</v-col>
<v-spacer></v-spacer>
<v-col cols="12" sm="4" md="4" lg="4" xl="3">
<v-text-field
v-model="search"
append-icon="mdi-magnify"
label="Поиск"
single-line
hide-details
clearable
:disabled="loading"
></v-text-field>
</v-col>
</v-row>
<v-data-table
:headers="headers"
:items="data.items"
:search="search"
item-key=" плавки"
@click:row="rowClick"
dense
>
<template v-slot:top>
<v-progress-linear v-if="loading" indeterminate></v-progress-linear>
</template>
</v-data-table>
<!-- fixed-header -->
</v-container>
</template>
<script>
let jsDate = new Date();
import { mapGetters, mapActions, mapMutations } from "vuex";
export default {
data: () => ({
search: "",
dates: [
new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() - 0)
.toISOString()
.substr(0, 10),
new Date().toISOString().substr(0, 10)
],
datePickerMenu: false
}),
computed: {
...mapGetters("LadleUse", {
loading: "loading",
data: "data"
}),
computedDateFormatted() {
let formatDates = [];
formatDates.push(this.formatDate(this.dates[0]));
formatDates.push(this.formatDate(this.dates[1]));
return formatDates.join(" ~ ");
},
headers() {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Roboto, sans-serif";
this.data.headers.forEach(element => {
element.divider = true;
element.align = "center";
});
return this.data.headers;
}
},
methods: {
...mapMutations("LadleUse", {
getExcel: "getExcel"
}),
...mapActions("LadleUse", {
getData: "getData"
}),
Excel() {
this.getExcel([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
},
rowClick: function(item, row) {
let selectState = row.isSelected ? false : true;
row.select(selectState);
},
input(e) {
if (e.length == 2) {
this.datePickerMenu = false;
}
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
refreshData() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
}
},
mounted() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
}
};
</script>
<style>
.datePicker input {
text-align: center;
cursor: pointer;
}
#ladleUse .v-data-table table > tbody > tr > td:nth-child(1),
#ladleUse .v-data-table table > thead > tr > th:nth-child(1) {
position: sticky !important;
position: -webkit-sticky !important;
left: 0;
background-color: #fafafa !important;
}
#ladleUse .theme--light.v-data-table tbody tr.v-data-table__selected {
background: #f5c17d70 !important;
}
#ladleUse .theme--dark.v-data-table tbody tr.v-data-table__selected {
background: #a17b4970 !important;
}
#ladleUse .theme--dark.v-data-table tbody tr.v-data-table__selected:hover {
background: #a17b49c2 !important;
}
#ladleUse .theme--light.v-data-table tbody tr.v-data-table__selected:hover {
background: #ffd296d2 !important;
}
#ladleUse .spacer {
margin-top: 3em;
}
#ladleUse .divider {
border-right: rgba(0, 0, 0, 0.12) solid 1px;
}
#ladleUse .v-data-table {
border: thin solid rgba(0, 0, 0, 0.12);
border-radius: 0;
}
#ladleUse .v-data-table-header {
background-color: #fafafa !important;
}
#ladleUse #datePicker {
text-align: center;
}
</style>

View File

@@ -0,0 +1,392 @@
<template>
<v-container fluid id="PRB_FileControl" class="pa-10">
<v-card class="mx-auto" max-width="1000" tile>
<v-toolbar elevation="2" color="purple darken-2" dark>
<v-toolbar-title>
<v-list-item class="pa-0">
<v-avatar>
<v-icon x-large color="purple accent-1">
mdi-file-check
</v-icon>
</v-avatar>
<v-list-item-content class="pa-4">
<v-list-item-title class="text-h6">
ПРБ
</v-list-item-title>
<v-list-item-subtitle>
файловый менеджер
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn icon @click.stop="dialog.log = true">
<v-icon>{{ accountIcon }}</v-icon>
</v-btn>
<v-dialog v-model="dialog.log" max-width="350">
<v-card v-show="isLogging">
<v-card-title class="text-h5 grey lighten-2">
Администратор
</v-card-title>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="purple darken-2" dark @click="loggingOFF">
Выйти
</v-btn>
</v-card-actions>
</v-card>
<v-card style="height: 250px" v-show="!isLogging">
<v-card-title class="text-h5 grey lighten-2">
Введите пароль
</v-card-title>
<v-card-text>
<v-otp-input v-model="pass.val" @finish="passCheck" type="password" class="pt-4" length="6"></v-otp-input>
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-row>
<v-spacer></v-spacer>
<v-col cols="8">
<v-checkbox v-model="pass.select" label="запомнить пароль" color="purple darken-2"
hide-details></v-checkbox>
</v-col>
</v-row>
</v-card-actions>
</v-card>
</v-dialog>
</v-toolbar>
<v-container>
<v-toolbar flat>
<v-col style="min-width: 200px; max-width: 100px;">
<v-menu v-model="datePickerMenu" :close-on-content-click="false" :nudge-right="40" :nudge-top="-5"
transition="scale-transition" offset-y min-width="290px">
<template v-slot:activator="{ on }">
<v-text-field class="datePicker" v-model="computedDateFormatted" prepend-icon="event" readonly v-on="on"
outlined hide-details dense :disabled="loading" />
</template>
<v-date-picker popover-align="center" v-model="date" @input="datePickerMenu = false"
@change="getData(computedDateFormatted)"></v-date-picker>
</v-menu>
</v-col>
<v-col style="min-width: 295px;" v-show="isLogging">
<v-file-input @change="getFile" v-model="file.input" class="pt-7" label="Выберите файл (doc, xls)" outlined
dense accept=".xlsx, .docx, .xls, .doc"></v-file-input>
</v-col>
<v-btn :loading="loading_file" :disabled="!file.input" v-show="isLogging" color="success"
class="ma-2 white--text" @click="fileUpload">
Загрузить
<v-icon right dark>
mdi-cloud-upload
</v-icon>
</v-btn>
<v-spacer></v-spacer>
<v-btn icon :disabled="!selectState || loading" :href="baseURL + file.name" download
@click="setHistory(file.id)">
<v-icon>mdi-download</v-icon>
</v-btn>
<!-- <v-btn icon v-show="isLogging" :disabled="!selectState || loading">
<v-icon>mdi-pencil</v-icon>
</v-btn> -->
<v-btn icon color="red lighten-1" v-show="isLogging" :disabled="!selectState || loading" @click="deleteFile">
<v-icon>mdi-delete</v-icon>
</v-btn>
</v-toolbar>
<v-data-table :headers="headers" :items="data.items" :loading="loading" selectable-key="id"
@click:row="rowClick" single-select fixed-header disable-pagination hide-default-footer dense>
<template v-slot:item.file_name="{ item }">
<v-icon>
{{ getIcon(item.file_name) }}
</v-icon>
{{ item.file_name }}
</template>
<template v-slot:item.isCompleted="{ item }">
<v-simple-checkbox color="purple darken-2" :ripple="false" :value="item.isCompleted === 0 ? false : true"
@input="inputCompleted({ id: item.id, value: $event === true ? 1 : 0 })"></v-simple-checkbox>
</template>
<template v-slot:item.id="{ item }">
<v-btn class="ml-2" text icon
@click.stop="dialog.history = true; file.name = item.file_name; getHistory({ date: date, id: item.id })">
<v-icon>mdi-information</v-icon>
</v-btn>
</template>
</v-data-table>
</v-container>
</v-card>
<v-dialog v-model="dialog.history" transition="dialog-bottom-transition" max-width="700">
<v-card elevation>
<v-toolbar color="purple darken-2" dark>
<v-icon class="ma-2">
{{ getIcon(file.name) }}
</v-icon>
{{ file.name }}</v-toolbar>
<v-card-text class="pa-4">
<v-data-table :headers="history.headers" :items="history.items" :loading="loading_history" disable-pagination
hide-default-footer dense></v-data-table>
</v-card-text>
<v-card-actions class="justify-end">
<v-btn text @click="dialog.history = false">Закрыть</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-snackbar v-model="snackbar" vertical top right :color="snackbarColor">
{{ uploadText }}
<template v-slot:action="{ attrs }">
<v-btn text v-bind="attrs" @click="snackbar = false">
ok
</v-btn>
</template>
</v-snackbar>
</v-container>
</template>
<script>
import { mapGetters, mapActions, mapMutations } from "vuex";
export default {
data: vm => ({
file: { name: null, id: null, input: null, data: null },
dialog: { log: false, history: false },
pass: { val: null, select: true },
selectState: false,
snackbar: false,
date: new Date().toISOString().substr(0, 10),
dateFormatted: vm.formatDate(new Date().toISOString().substr(0, 10)),
datePickerMenu: false,
extensionsList: [
{ value: "mdi-file-excel", extension: ['xlsx'] },
{ value: "mdi-file-word", extension: ['docx'] },
]
}),
computed: {
...mapGetters("PRB_FileControl", {
loading: "loading",
loading_file: "loading_file",
loading_history: "loading_history",
isLogging: "isLogging",
uploadText: "uploadText",
uploadStatus: "uploadStatus",
data: "data",
history: "history",
}),
baseURL() {
return process.env.NODE_ENV === 'development'
? 'http://192.168.76.112//_api_server_vue/modules/PRB_FileControl/uploads/'
: 'http://192.168.76.100:81//_api_server_vue/modules/PRB_FileControl/uploads/'
},
headers() {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Roboto, sans-serif";
this.data.headers.forEach(element => {
if (!this.isLogging) {
if (element.value === "isCompleted") {
element.align = " d-none";
}
} else {
element.align = " visible";
}
if (!this.isLogging) {
if (element.value === "id") {
element.align = " d-none";
}
} else {
element.align = " visible";
}
if (element.value === "file_path") {
element.align = " d-none";
}
if (element.value === "isCompleted") {
element.width = '11%';
}
if (this.isLogging) {
if (element.value === "file_name") {
element.width = '60%';
}
} else {
if (element.value === "file_name") {
element.width = '80%';
}
}
// var metrics = ctx.measureText(element.text);
// var cellWidth = metrics.width;
// element.width = cellWidth + 65;
// element.align = "center";
// element.divider = true;
});
return this.data.headers;
},
computedDateFormatted() {
return this.formatDate(this.date);
},
accountIcon() {
return this.isLogging ? "mdi-account-check" : "mdi-account-off"
},
snackbarColor() {
return this.uploadStatus ? "green darken-4" : "red darken-4"
},
},
methods: {
...mapMutations("PRB_FileControl", {
setStorage: "setStorage",
}),
...mapActions("PRB_FileControl", {
File_Upload: "File_Upload",
getData: "getData",
getStorage: "getStorage",
logging: "logging",
logout: "logout",
setCompleted: "setCompleted",
setHistory: "setHistory",
getHistory: "getHistory",
deleteData: "deleteData",
}),
getIcon(ext) {
if (ext) {
let icon = this.extensionsList.find((item) => {
let { extension } = item;
if (Array.isArray(extension)) {
return extension.includes(ext.split('.').pop());
} else if (typeof extension === 'string') {
return extension === ext;
}
}) || {};
return icon.value || "mdi-file";
}
},
inputCompleted(item) {
this.setCompleted(item);
},
rowClick(item, row) {
this.selectState = row.isSelected ? false : true;
this.file.name = item.file_name;
this.file.id = item.id;
row.select(this.selectState);
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
passCheck() {
this.logging(this.pass.val);
if (this.pass.select) this.setStorage(this.pass.val)
this.dialog.log = false;
this.pass.val = "";
this.reload();
},
loggingOFF() {
this.logout();
this.dialog.log = false;
this.pass.val = "";
this.reload();
},
getFile(f) {
const formData = new FormData();
formData.append("file", f);
this.file.data = formData;
},
fileUpload() {
this.File_Upload({ file: this.file.data, date: this.formatDate(this.date) }).then(() => {
this.file.input = null;
this.getData(this.formatDate(this.date));
}).catch(() => {
this.file.input = null;
}).finally(() => {
this.snackbar = true;
})
},
deleteFile() {
this.deleteData({ id: this.file.id, name: this.file.name }).then(() => { this.reload() });
},
reload() {
this.getStorage();
this.getData(this.formatDate(this.date));
},
},
mounted() {
this.reload();
}
};
</script>
<style>
/*
#PRB_FileControl {
height: 100%;
width: 100%;
background: url(../assets/purple-color-moving-gradient-background.jpg) center !important;
}
*/
.datePicker input {
text-align: center;
cursor: pointer;
}
#PRB_FileControl .divider {
border-right: rgba(0, 0, 0, 0.12) solid 1px;
}
#PRB_FileControl .v-data-table {
border: thin solid rgba(0, 0, 0, 0.12);
border-radius: 0;
}
#PRB_FileControl .v-data-table-header {
background-color: #fafafa !important;
}
#PRB_FileControl #datePicker {
text-align: center;
}
.theme--light.v-data-table tbody tr.v-data-table__selected {
background: #f5c17d70 !important;
}
.theme--dark.v-data-table tbody tr.v-data-table__selected {
background: #a17b4970 !important;
}
.theme--dark.v-data-table tbody tr.v-data-table__selected:hover {
background: #a17b49c2 !important;
}
.theme--light.v-data-table tbody tr.v-data-table__selected:hover {
background: #ffd296d2 !important;
}
</style>

View File

@@ -0,0 +1,267 @@
<template>
<v-container id="KRO">
<v-card-text class="text-center headline black--text">
Отчет КРО за период {{computedDateFormatted}}
</v-card-text>
<v-divider class="mx-0"></v-divider>
<v-row>
<v-col style="min-width:250px; max-width:250px;" cols="12">
<v-menu
v-model="datePickerMenu"
:close-on-content-click="false"
:nudge-right="40"
:nudge-top="-5"
transition="scale-transition"
offset-y
min-width="290px"
>
<template v-slot:activator="{ on }">
<v-text-field
id="datePicker"
class="datePicker"
v-model="computedDateFormatted"
prepend-icon="event"
readonly
v-on="on"
single-line
:disabled="loading"
/>
</template>
<v-date-picker
no-title
scrollable
popover-align="center"
v-model="dates"
@input="input($event) && datePickerMenu"
@change="refreshData()"
range
></v-date-picker>
</v-menu>
</v-col>
<v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider>
<v-col class="text-center my-4" cols="1" sm="1">
<v-btn :disabled="loading" tile outlined color="success" @click="loader = Excel()">
<v-icon left size="35">mdi-file-excel</v-icon>Excel
</v-btn>
</v-col>
<v-spacer></v-spacer>
<v-col cols="12" sm="4" md="4" lg="4" xl="3">
<v-text-field
v-model="search"
append-icon="mdi-magnify"
label="Поиск"
single-line
hide-details
clearable
:disabled="loading"
></v-text-field>
</v-col>
</v-row>
<v-data-table
:headers="headers"
:items="data.items"
:loading="loading"
:search="search"
item-key=" плавки"
@click:row="rowClick"
dense
>
<template v-if="data.items.length" v-slot:header :class="header.visibility">
<thead class="grey lighten-5 text-center">
<tr>
<th id="header" class="text-center divider d-sm-table-cell" :colspan="1"></th>
<th
class="text-center divider d-none d-sm-table-cell"
:colspan="getIndexByName('Вес слябов')"
></th>
<th
class="text-center divider d-none d-sm-table-cell"
:colspan="getIndexByName('C')-getIndexByName('Вес слябов')-2"
>Материалы конвертер</th>
<th
class="text-center divider d-none d-sm-table-cell"
:colspan="getIndexByName('Бригада шихтовала')-getIndexByName('C')-1"
>Итоговая химия конвертер</th>
<th
class="text-center divider d-none d-sm-table-cell"
:colspan="getIndexByName('номер обработки')-getIndexByName('Бригада шихтовала')-1"
>Персонал</th>
<th
class="text-center divider d-none d-sm-table-cell"
:colspan="getIndexByName('температура с мнлз')-getIndexByName('номер обработки')+1"
>УКДС</th>
<th
class="text-center divider d-none d-sm-table-cell"
:colspan="getIndexByName('Al ')-getIndexByName('температура с мнлз')-2"
>Материалы УКДС</th>
<th
class="text-center divider d-none d-sm-table-cell"
:colspan="getIndexByName('Мастер УКП')-getIndexByName('Al ')"
>Итоговая химия УКДС</th>
<th class="text-center d-none d-sm-table-cell" :colspan="4">Персонал</th>
</tr>
</thead>
</template>
</v-data-table>
</v-container>
</template>
<script>
//, mapMutations, mapActions
let jsDate = new Date();
import { mapGetters, mapActions, mapMutations } from "vuex";
import { _ } from "vue-underscore";
export default {
data: () => ({
search: "",
dates: [
new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() - 0)
.toISOString()
.substr(0, 10),
new Date().toISOString().substr(0, 10)
],
datePickerMenu: false
}),
computed: {
...mapGetters("Pasport_KRO", {
loading: "loading",
data: "data"
}),
computedDateFormatted() {
let formatDates = [];
formatDates.push(this.formatDate(this.dates[0]));
formatDates.push(this.formatDate(this.dates[1]));
return formatDates.join(" ~ ");
},
headers() {
// var canvas = document.createElement("canvas");
// var ctx = canvas.getContext("2d");
// ctx.font = "12px Roboto, sans-serif";
// this.data.headers.forEach(element => {
// var metrics = ctx.measureText(element.text);
// var cellWidth = metrics.width;
// element.width = cellWidth + 65;
// element.align = "center";
// element.divider = true;
// if (element.value === "dateForSort" || element.value === "idGroup") {
// element.align = " d-none";
// }
// });
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Roboto, sans-serif";
this.data.headers.forEach(element => {
element.divider = true;
element.align = "center";
if (
element.value === "ID" ||
element.value === "BOFHR_ID" ||
element.value === "NEWNUMBER1" ||
element.value === "HEATNO" ||
element.value === "Heat"
) {
element.align = " d-none";
}
});
return this.data.headers;
}
},
methods: {
...mapMutations("Pasport_KRO", {
getExcel: "getExcel"
}),
...mapActions("Pasport_KRO", {
getData: "getData"
}),
Excel() {
this.getExcel([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
},
rowClick: function(item, row) {
let selectState = row.isSelected ? false : true;
row.select(selectState);
},
getIndexByName(value) {
return _.findIndex(this.headers, {
value: value
});
},
input(e) {
if (e.length == 2) {
this.datePickerMenu = false;
}
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
refreshData() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
}
},
mounted() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
}
};
</script>
<style>
#KRO .v-data-table table > tbody > tr > td:nth-child(2),
#KRO div.v-data-table__wrapper
> table
> thead.v-data-table-header
> tr
> th:nth-child(2),
#KRO .v-data-table table > thead > tr > th:nth-child(1) {
position: sticky !important;
position: -webkit-sticky !important;
left: 0;
background-color: #fafafa !important;
}
#KRO .datePicker input {
text-align: center;
cursor: pointer;
}
#KRO .theme--light.v-data-table tbody tr.v-data-table__selected {
background: #f5c17d70 !important;
}
#KRO .theme--dark.v-data-table tbody tr.v-data-table__selected {
background: #a17b4970 !important;
}
#KRO .theme--dark.v-data-table tbody tr.v-data-table__selected:hover {
background: #a17b49c2 !important;
}
#KRO .theme--light.v-data-table tbody tr.v-data-table__selected:hover {
background: #ffd296d2 !important;
}
#KRO .spacer {
margin-top: 3em;
}
#KRO .divider {
border-right: rgba(0, 0, 0, 0.12) solid 1px;
}
#KRO .v-data-table {
border: thin solid rgba(0, 0, 0, 0.12);
border-radius: 0;
}
#KRO .v-data-table-header {
background-color: #fafafa !important;
}
#KRO #datePicker {
text-align: center;
}
</style>

View File

@@ -0,0 +1,222 @@
<template>
<!-- <v-container fluid id="BOFReport" class="myContainer" style="background-color:rgba(0, 0, 0, 0.43);"> -->
<v-container id="crewAggregateWeight">
<v-card-text
class="text-center headline black--text"
>Вес стали по агрегатам за период {{computedDateFormatted}}</v-card-text>
<v-divider class="mx-0"></v-divider>
<v-row>
<v-col style="min-width:250px; max-width:250px;" cols="12">
<v-menu
v-model="datePickerMenu"
:close-on-content-click="false"
:nudge-right="40"
:nudge-top="-5"
transition="scale-transition"
offset-y
min-width="290px"
>
<template v-slot:activator="{ on }">
<v-text-field
id="datePicker"
class="datePicker"
v-model="computedDateFormatted"
prepend-icon="event"
readonly
v-on="on"
single-line
:disabled="loading"
/>
</template>
<v-date-picker
no-title
scrollable
popover-align="center"
v-model="dates"
@input="input($event) && datePickerMenu"
@change="refreshData()"
range
></v-date-picker>
</v-menu>
</v-col>
<!-- <v-divider class="d-none d-md-flex mx-2 my-7" inset vertical></v-divider> -->
<!-- <v-col class="text-center my-4" cols="1" sm="1">
<v-btn :disabled="loading" tile outlined color="success" @click="loader = Excel()">
<v-icon left size="35">mdi-file-excel</v-icon>Excel
</v-btn>
</v-col> -->
<v-spacer></v-spacer>
<v-col cols="12" sm="4" md="4" lg="4" xl="3">
<v-text-field
v-model="search"
append-icon="mdi-magnify"
label="Поиск"
single-line
hide-details
clearable
:disabled="loading"
></v-text-field>
</v-col>
</v-row>
<v-data-table
:headers="headers"
:items="data.items"
:search="search"
item-key="crew"
@click:row="rowClick"
disable-pagination
hide-default-footer
dense
>
<template v-slot:top>
<v-progress-linear v-if="loading" indeterminate></v-progress-linear>
</template>
<template v-if="data.items.length" v-slot:header :class="header.visibility">
<thead class="grey lighten-5 text-center">
<tr>
<th class="text-center divider d-none d-sm-table-cell" :colspan="1"></th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="2">К1</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="2">К2</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="2">Печь-ковш</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="2">МНЛЗ-1</th>
<th class="text-center divider d-none d-sm-table-cell" :colspan="2">МНЛЗ-2</th>
</tr>
</thead>
</template>
</v-data-table>
<!-- fixed-header -->
</v-container>
</template>
<script>
let jsDate = new Date();
import { mapGetters, mapActions, mapMutations } from "vuex";
export default {
data: () => ({
search: "",
dates: [
new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate() - 0)
.toISOString()
.substr(0, 10),
new Date().toISOString().substr(0, 10)
],
datePickerMenu: false
}),
computed: {
...mapGetters("crewAggregateWeight", {
loading: "loading",
data: "data"
}),
computedDateFormatted() {
let formatDates = [];
formatDates.push(this.formatDate(this.dates[0]));
formatDates.push(this.formatDate(this.dates[1]));
return formatDates.join(" ~ ");
},
headers() {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Roboto, sans-serif";
this.data.headers.forEach(element => {
element.divider = true;
element.align = "center";
});
return this.data.headers;
}
},
methods: {
...mapMutations("LadleUse", {
getExcel: "getExcel"
}),
...mapActions("crewAggregateWeight", {
getData: "getData"
}),
Excel() {
this.getExcel([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
},
rowClick: function(item, row) {
let selectState = row.isSelected ? false : true;
row.select(selectState);
},
input(e) {
if (e.length == 2) {
this.datePickerMenu = false;
}
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
refreshData() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
}
},
mounted() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
}
};
</script>
<style>
.datePicker input {
text-align: center;
cursor: pointer;
}
#crewAggregateWeight .v-data-table-header {
background-color: #fafafa !important;
}
#crewAggregateWeight .spacer {
margin-top: 3em;
}
#crewAggregateWeight .divider {
border-right: rgba(0, 0, 0, 0.12) solid 1px;
}
#crewAggregateWeight .v-data-table {
border-left: thin solid rgba(0, 0, 0, 0.12);
border-top: thin solid rgba(0, 0, 0, 0.12);
border-bottom: thin solid rgba(0, 0, 0, 0.12);
border-radius: 0;
}
#crewAggregateWeight .v-data-table table>tbody>tr>td {
border-right: thin solid rgba(0, 0, 0, 0.12);
}
#crewAggregateWeight #datePicker {
text-align: center;
}
.theme--light.v-data-table tbody tr.v-data-table__selected {
background: #f5c17d70 !important;
}
.theme--dark.v-data-table tbody tr.v-data-table__selected {
background: #a17b4970 !important;
}
.theme--dark.v-data-table tbody tr.v-data-table__selected:hover {
background: #a17b49c2 !important;
}
.theme--light.v-data-table tbody tr.v-data-table__selected:hover {
background: #ffd296d2 !important;
}
</style>

110
src/components/index.vue Normal file
View File

@@ -0,0 +1,110 @@
<template>
<v-container id="stat" fill-height>
<v-card class="mx-auto" tile elevation="5">
<v-img height="200" width="750" src="../assets/2.png"></v-img>
<v-card-title>
<v-icon color="teal lighten-3" large left>mdi-apps</v-icon>
<span>APP-VUE-HUB ({{ items.length }} projects<span v-if="!loading"> | {{ allCounts }} visits</span>)</span>
</v-card-title>
<v-progress-linear v-if="loading" indeterminate></v-progress-linear>
<v-divider></v-divider>
<v-list two-line id="scrolling-techniques-7" class="overflow-y-auto" max-height="450" max-width="750">
<v-list-item-group>
<v-list-item v-for="(item, i) in items" :key="item.index" :to="{ path: item.path }">
<v-list-item-content>
<v-list-item-title>{{ ++i }} - {{ item.name }}</v-list-item-title>
<v-list-item-subtitle>URL:{{ item.path }}</v-list-item-subtitle>
</v-list-item-content>
<span id="myheaders" class="text--secondary overline"
v-if="item.counters !== 'undefined visits |' && !loading">
<span class="pa-md-2 mx-lg-auto "><v-chip small>{{ item.counters
}}</v-chip></span>
<span class=" mx-lg-auto ">visits \ </span>
<span class=" mx-lg-auto ">last </span>
<span class=" mx-lg-auto "><v-chip small>{{ item.last_date }}</v-chip></span>
<v-list-item-action>
<v-btn icon @click.native.prevent="showInfo(item.name)">
<v-icon color="grey lighten-1">mdi-information</v-icon>
</v-btn>
</v-list-item-action>
</span>
</v-list-item>
</v-list-item-group>
</v-list>
<v-divider></v-divider>
<v-list subheader>
<v-subheader class="overline">БОТП АСУТП ККЦ - Самофалов Д.А.</v-subheader>
</v-list>
</v-card>
</v-container>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
import { _ } from "vue-underscore";
export default {
data: () => ({
allCounts: 0,
items: [],
}),
computed: {
...mapGetters("stat", {
loading: "loading",
data: "data"
})
},
methods: {
...mapActions("stat", {
getData: "getData"
}),
showInfo(e) {
this.$router.props = e;
this.$router.push('/stat')
},
},
mounted() {
this.$router.options.routes.forEach(element => {
if ((element.path !== "/") && (element.path !== "/stat")) {
this.items.push(
{ name: element.name, path: element.path }
)
}
});
this.getData().then(() => {
this.items = this.items.map((arr) => {
return {
...arr,
counters: _.defaults(_.findWhere(this.data.stat, {
project_name: arr.name
})).project_count,
last_date: _.defaults(_.findWhere(this.data.stat, {
project_name: arr.name,
})).last_date
};
});
this.data.stat.forEach(element => {
if (element.project_name !== 'Stat') {
this.allCounts = this.allCounts + element.project_count
}
});
});
}
};
</script>
<style>
.container {
max-width: 100% !important;
}
#myheaders {
font-size: 12px !important;
}
#stat {
height: 100%;
width: 100%;
background: url(../assets/1.png) center !important;
}
</style>

View File

@@ -0,0 +1,389 @@
<style>
.datePicker input {
text-align: center;
cursor: pointer;
}
#mytable .v-data-table__wrapper {
max-height: 430px;
}
.container {
max-width: 100% !important;
}
#myContainer,
body,
html {
padding: 0;
}
/* tbody tr:nth-of-type(odd) {
background-color: rgba(0, 0, 0, .05);
} */
/* #mytable table thead tr th {
background: #e0e0e0;
} */
</style>
<template>
<div id="myContainer">
<v-container>
<v-card tile>
<v-tabs
:value="!persons.show_all?services.default:[]"
background-color="primary"
dark
show-arrows
>
<v-tabs-slider></v-tabs-slider>
<v-tab
v-for="item in services.all"
:key="item.ID_SERVICE"
@change="change_service(item.ID_SERVICE)"
:disabled="item.COUNT==0 || persons.show_all"
>
<div v-if="item.COUNT">
<v-badge
left
color="blue darken-4"
inline
:value="!persons.show_all?item.COUNT:0"
:content="item.COUNT"
>{{ item.SERVICE }}</v-badge>
</div>
<div v-else>
<v-badge left color="blue darken-4" inline content="0">{{ item.SERVICE }}</v-badge>
</div>
</v-tab>
</v-tabs>
</v-card>
<v-sheet style="background-color:rgba(0, 0, 0, 0.43);" dark tile>
<v-container>
<v-row justify="center" no-gutters>
<v-col style="max-width: 400px;" xl="2" lg="4" sm="4" md="5">
<v-card-title dense>
<v-select
:value="!departments.show_all?departments.default:[]"
:items="departments.current"
item-value="ID_DEPARTMENT"
item-text="DEPARTMENT"
label="Подразделение"
outlined
hide-details
dense
:disabled="departments.show_all"
@change="change_department($event)"
>
<template v-slot:selection="data">{{ data.item.DEPARTMENT }}</template>
<template v-slot:item="data">
<div v-if="data.item.COUNT!=0">
<v-badge
color="blue-grey lighten-2"
light
left
inline
:content="data.item.COUNT"
>{{ data.item.DEPARTMENT }}</v-badge>
</div>
<div v-else>
<v-badge
color="blue-grey lighten-4"
light
left
inline
content="0"
>{{ data.item.DEPARTMENT }}</v-badge>
</div>
</template>
</v-select>
<v-switch
color="orange"
v-show="persons.all.length"
:input-value="departments.show_all"
hide-details
label="Все подразделения"
@change="all_departments($event)"
></v-switch>
</v-card-title>
</v-col>
<v-col style="max-width: 400px;" lg="2" sm="4" md="3">
<v-card-title dense>
<v-select
:value="!crews.show_all?crews.default:[]"
:items="crews.current"
item-value="CREW"
item-text="CREW_DESC"
label="Бригада"
outlined
hide-details
dense
:disabled="crews.show_all"
@change="change_crew($event)"
>
<template v-slot:selection="data">{{ data.item.CREW_DESC }}</template>
<template v-slot:item="data">
<div v-if="data.item.COUNT!=0">
<v-badge
color="blue-grey lighten-2"
light
left
inline
:content="data.item.COUNT"
>{{ data.item.CREW_DESC }}</v-badge>
</div>
<div v-else>
<v-badge
color="blue-grey lighten-4"
light
left
inline
content="0"
>{{ data.item.CREW_DESC }}</v-badge>
</div>
</template>
</v-select>
<v-switch
color="orange"
v-show="persons.all.length"
:input-value="crews.show_all"
@change="all_crews($event)"
hide-details
label="Все бригады"
></v-switch>
</v-card-title>
</v-col>
<v-col style="max-width: 400px;" justify="center" lg="3" sm="3" md="3">
<v-card-title dense>
<v-menu
v-model="datePickerMenu"
:close-on-content-click="false"
:nudge-right="40"
:nudge-top="-5"
transition="scale-transition"
offset-y
min-width="290px"
>
<template v-slot:activator="{ on }">
<v-text-field
class="datePicker"
v-model="computedDateFormatted"
label="Период"
prepend-icon="event"
readonly
v-on="on"
outlined
hide-details
dense
:disabled="loading"
/>
</template>
<v-date-picker
popover-align="center"
v-model="date"
@input="datePickerMenu = false"
@change="get_allData(computedDateFormatted)"
></v-date-picker>
</v-menu>
<v-switch
color="orange"
v-show="persons.all.length"
hide-details
label="Весь персонал"
:input-value="persons.show_all"
@change="all_persons($event)"
></v-switch>
</v-card-title>
</v-col>
</v-row>
</v-container>
</v-sheet>
<v-card color="primary" dark tile>
<v-progress-linear color="orange" rounded :value="progress" reactive></v-progress-linear>
<v-card-title>
<div v-if="persons.all.length">
<v-badge
color="blue darken-4"
offset-x="-2"
:content="`${persons.count.in} / ${persons.count.out==undefined?0:persons.count.out}`"
overlap
>
<v-icon large class="px-2">schedule</v-icon>Проходная 2.0
</v-badge>
</div>
<div v-else>
<v-icon large class="px-2">schedule</v-icon>Проходная 2.0
</div>
<v-spacer></v-spacer>
<v-text-field
v-model="search"
append-icon="mdi-magnify"
label="Поиск"
single-line
hide-details
flat
></v-text-field>
</v-card-title>
<v-data-table
id="mytable"
fixed-header
:loading="loading"
:headers="headers"
:items="persons.current"
:search="search"
:sort-by="['DATE_IN']"
light
>
<!-- <template v-slot:footer>
:server-items-length="persons.current.length"
<div>
This is a footer
</div>
</template>-->
</v-data-table>
</v-card>
</v-container>
</div>
</template>
<script>
import { mapGetters, mapMutations, mapActions } from "vuex";
export default {
data: vm => ({
progress: 100,
timerID: null,
search: "",
headers: [
{
text: "Таб №",
value: "TAB",
width: 90
},
{
text: "ФИО",
value: "FIO",
divider: true
},
{
text: "Бригада",
value: "CREW",
width: 100
},
{
text: "Служба",
value: "SERVICE",
width: 100
},
{
text: "Подразделение",
value: "DEPARTMENT",
divider: true
},
{
text: "Время входа",
value: "DATE_IN",
width: 140
},
{
text: "Время выхода",
value: "DATE_OUT",
width: 140
}
],
date: new Date().toISOString().substr(0, 10),
dateFormatted: vm.formatDate(new Date().toISOString().substr(0, 10)),
datePickerMenu: false
}),
computed: {
...mapGetters("prohodnaya", {
loading: "loading",
services: "services",
departments: "departments",
crews: "crews",
persons: "persons"
}),
computedDateFormatted() {
return this.formatDate(this.date);
}
},
watch: {
progress() {}
},
methods: {
...mapActions("prohodnaya", {
get_allData: "get_allData"
}),
...mapMutations("prohodnaya", {
change_service: "change_service",
change_department: "change_department",
change_crew: "change_crew",
all_departments: "all_departments",
all_crews: "all_crews",
all_persons: "all_persons"
}),
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
progressValue() {
this.timerID = setInterval(() => {
this.progress = (this.progress - 0.02).toFixed(2);
if (this.progress < 0) {
this.progress = 101;
this.get_allData(this.formatDate(this.date));
}
}, 60);
}
},
mounted() {
this.progressValue();
this.get_allData(this.formatDate(this.date));
// this.get_persons()
// .then(response => {
// console.log(response);
// // this.persons = response;
// this.loading = false;
// })
// .catch(error => {
// console.log(error);
// });
// this.$store
// .dispatch("prohodnaya/get")
// .then(response => {
// this.data = response.data;
// this.loading = false;
// //console.log(response);
// })
// .catch(error => {
// console.log(error);
// });
// console.log(this.departments);
// this.get_services()
// .then(response => {
// this.services = response;
// })
// .catch(error => {
// console.log(error);
// });
// this.$store
// .dispatch("prohodnaya/get_services")
// .then(response => {
// this.test = response;
// console.log(response);
// })
// .catch(error => {
// console.log(error);
// });
//this.get_allData(this.formatDate(this.date));
},
beforeDestroy() {
clearInterval(this.timerID);
}
};
</script>

58
src/components/stat.vue Normal file
View File

@@ -0,0 +1,58 @@
<template>
<v-container id="stat" fill-height>
<v-card class="mx-auto" tile elevation="5">
<v-btn icon :to="{ path: '/' }">
<v-icon>mdi-arrow-left</v-icon>
</v-btn>
<v-card-title>
<span v-if="data.statInfo.length" class="font-weight-black">{{ $router.props }} - {{ data.statInfo.length }}
visits</span>
</v-card-title>
<v-progress-linear v-if="loading" indeterminate></v-progress-linear>
<v-divider></v-divider>
<v-list two-line id="scrolling-techniques-7" class="overflow-y-auto" height="500" width="1000" max-height="500"
max-width="1000">
<v-data-table :headers="data.headers" :items="data.statInfo" disable-pagination hide-default-footer>
</v-data-table>
</v-list>
</v-card>
</v-container>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
export default {
data: () => ({}),
computed: {
...mapGetters("stat", {
loading: "loading",
data: "data"
})
},
methods: {
...mapActions("stat", {
getData: "getDataInfo"
}),
},
mounted() {
this.getData(this.$router.props).then(() => { });
}
};
</script>
<style>
.container {
max-width: 100% !important;
}
#myheaders {
font-size: 12px !important;
}
#stat {
height: 100%;
width: 100%;
background: url(../assets/1.png) center !important;
}
</style>

View File

@@ -0,0 +1,270 @@
<template>
<v-container fluid id="myContainer">
<v-row justify="center">
<v-col cols="12" md="10" sm="8" lg="8" xl="6">
<v-card outlined tile>
<v-card-title>
<v-icon large left>mdi-database</v-icon>
<span>{{`Замеры температуры промковша МНЛЗ 1`}}</span>
<v-col style="min-width:290px; max-width:260px;" cols="12" class="mx-4">
<v-menu
v-model="datePickerMenu"
:close-on-content-click="false"
:nudge-right="40"
:nudge-top="-5"
transition="scale-transition"
offset-y
min-width="290px"
>
<template v-slot:activator="{ on }">
<v-text-field
id="datePicker"
class="datePicker"
v-model="computedDateFormatted"
prepend-icon="event"
readonly
v-on="on"
single-line
hide-details
:disabled="loading"
filled
rounded
dense
/>
</template>
<v-date-picker
no-title
scrollable
popover-align="center"
v-model="dates"
@input="input($event) && datePickerMenu"
@change="refreshData()"
range
></v-date-picker>
</v-menu>
</v-col>
</v-card-title>
<!-- <v-row justify="end">
<v-col style="min-width:290px; max-width:260px;" cols="12" class="mx-4">
<v-menu
v-model="datePickerMenu"
:close-on-content-click="false"
:nudge-right="40"
:nudge-top="-5"
transition="scale-transition"
offset-y
min-width="290px"
>
<template v-slot:activator="{ on }">
<v-text-field
id="datePicker"
class="datePicker"
v-model="computedDateFormatted"
prepend-icon="event"
readonly
v-on="on"
single-line
hide-details
:disabled="loading"
filled
rounded
dense
/>
</template>
<v-date-picker
no-title
scrollable
popover-align="center"
v-model="dates"
@input="input($event) && datePickerMenu"
@change="refreshData()"
range
></v-date-picker>
</v-menu>
</v-col>
</v-row>-->
<v-data-table
:headers="heatHeaders"
:items="data.tundishHeats.items"
:loading="loading"
:single-expand="false"
item-key="HEAT_NAME"
show-expand
>
<template v-slot:item.data-table-expand="{item, expand, isExpanded}">
<v-btn
v-if="!isExpanded &&
needExpand(item.HEAT_NAME)"
@click="expand(true)"
small
icon
>
<v-icon>mdi-chevron-down</v-icon>
</v-btn>
<v-btn v-else-if="isExpanded" @click="expand(false)" small icon>
<v-icon>mdi-chevron-up</v-icon>
</v-btn>
<v-icon v-else>mdi-lock</v-icon>
</template>
<template v-if="data.tundishHeats.items.length" v-slot:expanded-item="{headers, item}">
<td class="pa-5" :colspan="5">
<v-simple-table style="display: inline-grid" id="mySimpleTable" dense>
<template v-slot:default>
<thead>
<tr class="v-data-table-header">
<th
v-for="(tHeader, index) in tundishHeaders"
:key="index"
:class="[tHeader.visibility, tHeader.divider]"
>{{tHeader.text}}</th>
</tr>
</thead>
<tbody v-for="(tundishValues, index) in data.tundishValues.items" :key="index">
<tr v-if="tundishValues.HEAT_NAME===item.HEAT_NAME">
<td
v-for="(tHeader, index) in tundishHeaders"
:key="index"
:class="[tHeader.visibility, tHeader.divider]"
>
<v-simple-checkbox
v-if="index==1"
:ripple="false"
:value="tundishValues.button_all===0?false:true"
></v-simple-checkbox>
<tr v-else>{{tundishValues[tHeader.value]}}</tr>
</td>
</tr>
</tbody>
</template>
</v-simple-table>
</td>
</template>
</v-data-table>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
import { smartHeight } from "../mixins/utils";
import { _ } from "vue-underscore";
export default {
mixins: [smartHeight],
data: () => ({
dates: [
new Date().toISOString().substr(0, 10),
new Date().toISOString().substr(0, 10)
],
datePickerMenu: false
}),
computed: {
...mapGetters("tundishSample", {
loading: "loading",
data: "data"
}),
heatHeaders() {
// this.data.tundishHeats.headers.forEach(element => {
// if (element.value === "HEAT_NAME") {
// element.text = "№ Плавки";
// }
// if (element.value === "OPEN_TIME") {
// element.text = "Время открытия";
// }
// if (element.value === "CLOSE_TIME") {
// element.text = "Время закрытия";
// }
// });
return this.data.tundishHeats.headers;
},
tundishHeaders() {
this.data.tundishValues.headers.forEach(element => {
if (element.text === "HEAT_NAME") {
element.visibility = "d-none";
}
if (element.value === "button_all") {
element.text = "Кнопка: да/нет";
}
if (element.value === "opc_T_sample_value") {
element.text = "Температура";
}
if (element.value === "count") {
element.text = "Счетчик";
}
if (element.value === "datetime") {
element.text = "Дата/время";
}
});
return this.data.tundishValues.headers;
},
computedDateFormatted() {
let formatDates = [];
formatDates.push(this.formatDate(this.dates[0]));
formatDates.push(this.formatDate(this.dates[1]));
return formatDates.join(" ~ ");
}
},
methods: {
...mapActions("tundishSample", {
getData: "getData"
}),
needExpand(HEAT_NAME) {
return _.where(this.data.tundishValues.items, {
HEAT_NAME: HEAT_NAME
}).length;
},
input(e) {
if (e.length == 2) {
this.datePickerMenu = false;
}
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
refreshData() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
}
},
mounted() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
}
};
</script>
<style>
.datePicker input {
text-align: center;
cursor: pointer;
}
.container {
max-width: 100% !important;
}
#myContainer .v-data-table {
border-top: thin solid rgba(0, 0, 0, 0.12);
border-radius: 0;
}
#myContainer .v-data-table-header {
background-color: #fafafa !important;
}
#mySimpleTable {
border-right: thin solid rgba(0, 0, 0, 0.12);
border-left: thin solid rgba(0, 0, 0, 0.12);
}
</style>

View File

@@ -0,0 +1,146 @@
<template>
<v-container id="myContainer">
<v-row justify="center">
<v-col cols="12" sm="8">
<v-card outlined tile>
<v-card-title>
<v-icon color='primary' large left>mdi-thermometer</v-icon>
<span>{{`Среднестатистическая температура окружающей среды`}}</span>
</v-card-title>
<v-row justify="end">
<v-col style="min-width:290px; max-width:260px;" cols="12" class="mx-4">
<v-menu
v-model="datePickerMenu"
:close-on-content-click="false"
:nudge-right="40"
:nudge-top="-5"
transition="scale-transition"
offset-y
min-width="290px"
>
<template v-slot:activator="{ on }">
<v-text-field
id="datePicker"
class="datePicker"
v-model="computedDateFormatted"
prepend-icon="event"
readonly
v-on="on"
single-line
hide-details
:disabled="loading"
filled
rounded
dense
/>
</template>
<v-date-picker
no-title
scrollable
popover-align="center"
v-model="dates"
@input="input($event) && datePickerMenu"
@change="refreshData()"
range
></v-date-picker>
</v-menu>
</v-col>
</v-row>
<!-- <v-divider /> -->
<v-data-table :headers="headers" :items="data.temperature" :loading="loading" />
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<style>
.datePicker input {
text-align: center;
cursor: pointer;
}
#mytable .v-data-table__wrapper {
max-height: 430px;
}
.container {
max-width: 100% !important;
}
/* tbody tr:nth-of-type(odd) {
background-color: rgba(0, 0, 0, .05);
} */
/* #mytable table thead tr th {
background: #e0e0e0;
} */
</style>
<script>
//, mapMutations, mapActions
import { mapGetters, mapActions } from "vuex";
export default {
data: () => ({
headers: [
{
text: "Дата",
sortable: true,
align: "center",
value: "dt"
},
{
text: "Средняя температура °С",
align: "center",
sortable: true,
value: "value"
}
],
dates: [
new Date().toISOString().substr(0, 10),
new Date().toISOString().substr(0, 10)
],
datePickerMenu: false
}),
computed: {
...mapGetters("weatherAvg", {
loading: "loading",
data: "data"
}),
computedDateFormatted() {
let formatDates = [];
formatDates.push(this.formatDate(this.dates[0]));
formatDates.push(this.formatDate(this.dates[1]));
return formatDates.join(" ~ ");
}
},
methods: {
...mapActions("weatherAvg", {
getData: "getData"
}),
input(e) {
if (e.length == 2) {
this.datePickerMenu = false;
}
},
formatDate(date) {
if (!date) return null;
const [year, month, day] = date.split("-");
return `${day}.${month}.${year}`;
},
refreshData() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
}
},
mounted() {
this.getData([
this.formatDate(this.dates[0]),
this.formatDate(this.dates[1])
]);
}
};
</script>

10
src/eslint.config.mjs Normal file
View File

@@ -0,0 +1,10 @@
import globals from "globals";
import pluginVue from "eslint-plugin-vue";
/** @type {import('eslint').Linter.Config[]} */
export default [
{files: ["**/*.{js,mjs,cjs,vue}"]},
{languageOptions: { globals: globals.browser }},
...pluginVue.configs["flat/essential"],
];

19
src/main.js Normal file
View File

@@ -0,0 +1,19 @@
import "./api";
import Vue from "vue";
import App from "./App.vue";
import store from "./store";
import router from "./routes";
import vuetify from "./plugins/vuetify";
import underscore from "vue-underscore";
Vue.config.productionTip = false;
Vue.use(underscore);
new Vue({
store,
router,
vuetify,
render: (h) => h(App),
}).$mount("#app");

23
src/mixins/utils.js Normal file
View File

@@ -0,0 +1,23 @@
export const smartHeight = {
data() {
return {
breakpoint: 0,
top: 0,
footer: 0,
};
},
methods: {
smartHeight(val) {
this.footer = this.$vuetify.application.footer;
this.breakpoint = this.$vuetify.breakpoint.height;
// this.top = this.$vuetify.application.top;
return this.breakpoint - this.top - this.footer - val;
},
},
// beforeUpdate() {
// this.footer = this.$vuetify.application.footer;
// this.breakpoint = this.$vuetify.breakpoint.height;
// this.top = this.$vuetify.application.top;
// console.log(this.breakpoint+'-'+this.top+'-'+this.footer)
// },
};

View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2014-2017 Guyon Roche
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
'use strict';
var PromishLib = require('../utils/promish');
function setValue(key, value, overwrite) {
if (overwrite === undefined) {
// only avoid overwrite if explicitly disabled
overwrite = true;
}
switch (key.toLowerCase()) {
case 'promise':
if (!overwrite && PromishLib.Promish) return;
PromishLib.Promish = value;
break;
default:
break;
}
}
module.exports = setValue;
//# sourceMappingURL=set-value.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../lib/config/set-value.js"],"names":["PromishLib","require","setValue","key","value","overwrite","undefined","toLowerCase","Promish","module","exports"],"mappings":"AAAA;;AAEA,IAAIA,aAAaC,QAAQ,kBAAR,CAAjB;;AAEA,SAASC,QAAT,CAAkBC,GAAlB,EAAuBC,KAAvB,EAA8BC,SAA9B,EAAyC;AACvC,MAAIA,cAAcC,SAAlB,EAA6B;AAC3B;AACAD,gBAAY,IAAZ;AACD;AACD,UAAQF,IAAII,WAAJ,EAAR;AACE,SAAK,SAAL;AACE,UAAI,CAACF,SAAD,IAAcL,WAAWQ,OAA7B,EAAsC;AACtCR,iBAAWQ,OAAX,GAAqBJ,KAArB;AACA;AACF;AACE;AANJ;AAQD;;AAEDK,OAAOC,OAAP,GAAiBR,QAAjB","file":"set-value.js","sourcesContent":["'use strict';\n\nvar PromishLib = require('../utils/promish');\n\nfunction setValue(key, value, overwrite) {\n if (overwrite === undefined) {\n // only avoid overwrite if explicitly disabled\n overwrite = true;\n }\n switch (key.toLowerCase()) {\n case 'promise':\n if (!overwrite && PromishLib.Promish) return;\n PromishLib.Promish = value;\n break;\n default:\n break;\n }\n}\n\nmodule.exports = setValue;\n"]}

169
src/plugins/exceljs/dist/es5/csv/csv.js vendored Normal file
View File

@@ -0,0 +1,169 @@
'use strict';
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var fs = require('fs');
var csv = require('fast-csv');
var moment = require('moment');
var PromishLib = require('../utils/promish');
var StreamBuf = require('../utils/stream-buf');
var utils = require('../utils/utils');
var CSV = module.exports = function (workbook) {
this.workbook = workbook;
this.worksheet = null;
};
/* eslint-disable quote-props */
var SpecialValues = {
'true': true,
'false': false,
'#N/A': { error: '#N/A' },
'#REF!': { error: '#REF!' },
'#NAME?': { error: '#NAME?' },
'#DIV/0!': { error: '#DIV/0!' },
'#NULL!': { error: '#NULL!' },
'#VALUE!': { error: '#VALUE!' },
'#NUM!': { error: '#NUM!' }
};
/* eslint-ensable quote-props */
CSV.prototype = {
readFile: function readFile(filename, options) {
var self = this;
options = options || {};
var stream;
return utils.fs.exists(filename).then(function (exists) {
if (!exists) {
throw new Error('File not found: ' + filename);
}
stream = fs.createReadStream(filename);
return self.read(stream, options);
}).then(function (worksheet) {
stream.close();
return worksheet;
});
},
read: function read(stream, options) {
var _this = this;
options = options || {};
return new PromishLib.Promish(function (resolve, reject) {
var csvStream = _this.createInputStream(options).on('worksheet', resolve).on('error', reject);
stream.pipe(csvStream);
});
},
createInputStream: function createInputStream(options) {
options = options || {};
var worksheet = this.workbook.addWorksheet(options.sheetName);
var dateFormats = options.dateFormats || [moment.ISO_8601, 'MM-DD-YYYY', 'YYYY-MM-DD'];
var map = options.map || function (datum) {
if (datum === '') {
return null;
}
if (!isNaN(datum)) {
return parseFloat(datum);
}
var dt = moment(datum, dateFormats, true);
if (dt.isValid()) {
return new Date(dt.valueOf());
}
var special = SpecialValues[datum];
if (special !== undefined) {
return special;
}
return datum;
};
var csvStream = csv(options).on('data', function (data) {
worksheet.addRow(data.map(map));
}).on('end', function () {
csvStream.emit('worksheet', worksheet);
});
return csvStream;
},
write: function write(stream, options) {
var _this2 = this;
return new PromishLib.Promish(function (resolve, reject) {
options = options || {};
// var encoding = options.encoding || 'utf8';
// var separator = options.separator || ',';
// var quoteChar = options.quoteChar || '\'';
var worksheet = _this2.workbook.getWorksheet(options.sheetName || options.sheetId);
var csvStream = csv.createWriteStream(options);
stream.on('finish', function () {
resolve();
});
csvStream.on('error', reject);
csvStream.pipe(stream);
var dateFormat = options.dateFormat;
var dateUTC = options.dateUTC;
var map = options.map || function (value) {
if (value) {
if (value.text || value.hyperlink) {
return value.hyperlink || value.text || '';
}
if (value.formula || value.result) {
return value.result || '';
}
if (value instanceof Date) {
if (dateFormat) {
dateUTC ? moment.utc(value).format(dateFormat) : moment(value).format(dateFormat);
}
return dateUTC ? moment.utc(value).format() : moment(value).format();
}
if (value.error) {
return value.error;
}
if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {
return JSON.stringify(value);
}
}
return value;
};
var includeEmptyRows = options.includeEmptyRows === undefined || options.includeEmptyRows;
var lastRow = 1;
if (worksheet) {
worksheet.eachRow(function (row, rowNumber) {
if (includeEmptyRows) {
while (lastRow++ < rowNumber - 1) {
csvStream.write([]);
}
}
var values = row.values;
values.shift();
csvStream.write(values.map(map));
lastRow = rowNumber;
});
}
csvStream.end();
});
},
writeFile: function writeFile(filename, options) {
options = options || {};
var streamOptions = {
encoding: options.encoding || 'utf8'
};
var stream = fs.createWriteStream(filename, streamOptions);
return this.write(stream, options);
},
writeBuffer: function writeBuffer(options) {
var self = this;
var stream = new StreamBuf();
return self.write(stream, options).then(function () {
return stream.read();
});
}
};
//# sourceMappingURL=csv.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,72 @@
'use strict';
var events = require('events');
var utils = require('../utils/utils');
var LineBuffer = module.exports = function (options) {
events.EventEmitter.call(this);
this.encoding = options.encoding;
this.buffer = null;
// part of cork/uncork
this.corked = false;
this.queue = [];
};
utils.inherits(LineBuffer, events.EventEmitter, {
// Events:
// line: here is a line
// done: all lines emitted
write: function write(chunk) {
// find line or lines in chunk and emit them if not corked
// or queue them if corked
var data = this.buffer ? this.buffer + chunk : chunk;
var lines = data.split(/\r?\n/g);
// save the last line
this.buffer = lines.pop();
lines.forEach(function (line) {
if (this.corked) {
this.queue.push(line);
} else {
this.emit('line', line);
}
});
return !this.corked;
},
cork: function cork() {
this.corked = true;
},
uncork: function uncork() {
this.corked = false;
this._flush();
// tell the source I'm ready again
this.emit('drain');
},
setDefaultEncoding: function setDefaultEncoding() {
// ?
},
end: function end() {
if (this.buffer) {
this.emit('line', this.buffer);
this.buffer = null;
}
this.emit('done');
},
_flush: function _flush() {
if (!this.corked) {
this.queue.forEach(function (line) {
this.emit('line', line);
});
this.queue = [];
}
}
});
//# sourceMappingURL=line-buffer.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../lib/csv/line-buffer.js"],"names":["events","require","utils","LineBuffer","module","exports","options","EventEmitter","call","encoding","buffer","corked","queue","inherits","write","chunk","data","lines","split","pop","forEach","line","push","emit","cork","uncork","_flush","setDefaultEncoding","end"],"mappings":"AAAA;;AAEA,IAAIA,SAASC,QAAQ,QAAR,CAAb;;AAEA,IAAIC,QAAQD,QAAQ,gBAAR,CAAZ;;AAGA,IAAIE,aAAaC,OAAOC,OAAP,GAAiB,UAASC,OAAT,EAAkB;AAClDN,SAAOO,YAAP,CAAoBC,IAApB,CAAyB,IAAzB;AACA,OAAKC,QAAL,GAAgBH,QAAQG,QAAxB;;AAEA,OAAKC,MAAL,GAAc,IAAd;;AAEA;AACA,OAAKC,MAAL,GAAc,KAAd;AACA,OAAKC,KAAL,GAAa,EAAb;AACD,CATD;;AAWAV,MAAMW,QAAN,CAAeV,UAAf,EAA2BH,OAAOO,YAAlC,EAAgD;AAC9C;AACA;AACA;;AAEAO,SAAO,eAASC,KAAT,EAAgB;AACrB;AACA;AACA,QAAIC,OAAO,KAAKN,MAAL,GAAc,KAAKA,MAAL,GAAcK,KAA5B,GAAoCA,KAA/C;AACA,QAAIE,QAAQD,KAAKE,KAAL,CAAW,QAAX,CAAZ;;AAEA;AACA,SAAKR,MAAL,GAAcO,MAAME,GAAN,EAAd;;AAEAF,UAAMG,OAAN,CAAc,UAASC,IAAT,EAAe;AAC3B,UAAI,KAAKV,MAAT,EAAiB;AACf,aAAKC,KAAL,CAAWU,IAAX,CAAgBD,IAAhB;AACD,OAFD,MAEO;AACL,aAAKE,IAAL,CAAU,MAAV,EAAkBF,IAAlB;AACD;AACF,KAND;;AAQA,WAAO,CAAC,KAAKV,MAAb;AACD,GAvB6C;AAwB9Ca,QAAM,gBAAW;AACf,SAAKb,MAAL,GAAc,IAAd;AACD,GA1B6C;AA2B9Cc,UAAQ,kBAAW;AACjB,SAAKd,MAAL,GAAc,KAAd;AACA,SAAKe,MAAL;;AAEA;AACA,SAAKH,IAAL,CAAU,OAAV;AACD,GAjC6C;AAkC9CI,sBAAoB,8BAAW;AAC7B;AACD,GApC6C;AAqC9CC,OAAK,eAAW;AACd,QAAI,KAAKlB,MAAT,EAAiB;AACf,WAAKa,IAAL,CAAU,MAAV,EAAkB,KAAKb,MAAvB;AACA,WAAKA,MAAL,GAAc,IAAd;AACD;AACD,SAAKa,IAAL,CAAU,MAAV;AACD,GA3C6C;;AA6C9CG,UAAQ,kBAAW;AACjB,QAAI,CAAC,KAAKf,MAAV,EAAkB;AAChB,WAAKC,KAAL,CAAWQ,OAAX,CAAmB,UAASC,IAAT,EAAe;AAChC,aAAKE,IAAL,CAAU,MAAV,EAAkBF,IAAlB;AACD,OAFD;AAGA,WAAKT,KAAL,GAAa,EAAb;AACD;AACF;AApD6C,CAAhD","file":"line-buffer.js","sourcesContent":["'use strict';\n\nvar events = require('events');\n\nvar utils = require('../utils/utils');\n\n\nvar LineBuffer = module.exports = function(options) {\n events.EventEmitter.call(this);\n this.encoding = options.encoding;\n\n this.buffer = null;\n\n // part of cork/uncork\n this.corked = false;\n this.queue = [];\n};\n\nutils.inherits(LineBuffer, events.EventEmitter, {\n // Events:\n // line: here is a line\n // done: all lines emitted\n\n write: function(chunk) {\n // find line or lines in chunk and emit them if not corked\n // or queue them if corked\n var data = this.buffer ? this.buffer + chunk : chunk;\n var lines = data.split(/\\r?\\n/g);\n\n // save the last line\n this.buffer = lines.pop();\n\n lines.forEach(function(line) {\n if (this.corked) {\n this.queue.push(line);\n } else {\n this.emit('line', line);\n }\n });\n\n return !this.corked;\n },\n cork: function() {\n this.corked = true;\n },\n uncork: function() {\n this.corked = false;\n this._flush();\n\n // tell the source I'm ready again\n this.emit('drain');\n },\n setDefaultEncoding: function() {\n // ?\n },\n end: function() {\n if (this.buffer) {\n this.emit('line', this.buffer);\n this.buffer = null;\n }\n this.emit('done');\n },\n\n _flush: function() {\n if (!this.corked) {\n this.queue.forEach(function(line) {\n this.emit('line', line);\n });\n this.queue = [];\n }\n }\n});\n"]}

View File

@@ -0,0 +1,132 @@
'use strict';
// =======================================================================================================
// StreamConverter
//
// convert between encoding schemes in a stream
// Work in Progress - Will complete this at some point
var jconv;
var StreamConverter = module.exports = function (inner, options) {
this.inner = inner;
options = options || {};
this.innerEncoding = (options.innerEncoding || 'UTF8').toUpperCase();
this.outerEncoding = (options.outerEncoding || 'UTF8').toUpperCase();
this.innerBOM = options.innerBOM || null;
this.outerBOM = options.outerBOM || null;
this.writeStarted = false;
};
StreamConverter.prototype.convertInwards = function (data) {
if (data) {
if (typeof data === 'string') {
data = new Buffer(data, this.outerEncoding);
}
if (this.innerEncoding !== this.outerEncoding) {
data = jconv.convert(data, this.outerEncoding, this.innerEncoding);
}
}
return data;
};
StreamConverter.prototype.convertOutwards = function (data) {
if (typeof data === 'string') {
data = new Buffer(data, this.innerEncoding);
}
if (this.innerEncoding !== this.outerEncoding) {
data = jconv.convert(data, this.innerEncoding, this.outerEncoding);
}
return data;
};
StreamConverter.prototype.addListener = function (event, handler) {
this.inner.addListener(event, handler);
};
StreamConverter.prototype.removeListener = function (event, handler) {
this.inner.removeListener(event, handler);
};
StreamConverter.prototype.write = function (data, encoding, callback) {
if (encoding instanceof Function) {
callback = encoding;
encoding = undefined;
}
if (!this.writeStarted) {
// if inner encoding has BOM, write it now
if (this.innerBOM) {
this.inner.write(this.innerBOM);
}
// if outer encoding has BOM, delete it now
if (this.outerBOM) {
if (data.length <= this.outerBOM.length) {
if (callback) {
callback();
}
return;
}
var bomless = new Buffer(data.length - this.outerBOM.length);
data.copy(bomless, 0, this.outerBOM.length, data.length);
data = bomless;
}
this.writeStarted = true;
}
this.inner.write(this.convertInwards(data), encoding ? this.innerEncoding : undefined, callback);
};
StreamConverter.prototype.read = function () {
// TBD
};
StreamConverter.prototype.pipe = function (destination, options) {
var reverseConverter = new StreamConverter(destination, {
innerEncoding: this.outerEncoding,
outerEncoding: this.innerEncoding,
innerBOM: this.outerBOM,
outerBOM: this.innerBOM
});
this.inner.pipe(reverseConverter, options);
};
StreamConverter.prototype.close = function () {
this.inner.close();
};
StreamConverter.prototype.on = function (type, callback) {
var _this = this;
switch (type) {
case 'data':
this.inner.on('data', function (chunk) {
callback(_this.convertOutwards(chunk));
});
return this;
default:
this.inner.on(type, callback);
return this;
}
};
StreamConverter.prototype.once = function (type, callback) {
this.inner.once(type, callback);
};
StreamConverter.prototype.end = function (chunk, encoding, callback) {
this.inner.end(this.convertInwards(chunk), this.innerEncoding, callback);
};
StreamConverter.prototype.emit = function (type, value) {
this.inner.emit(type, value);
};
//# sourceMappingURL=stream-converter.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,49 @@
'use strict';
var Anchor = module.exports = function () {
var model = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
this.nativeCol = model.nativeCol || 0;
this.nativeColOff = model.nativeColOff || 0;
this.nativeRow = model.nativeRow || 0;
this.nativeRowOff = model.nativeRowOff || 0;
if (model.col) {
this.col = model.col;
}
if (model.row) {
this.row = model.row;
}
};
Anchor.asInstance = function (model) {
return model instanceof Anchor || model == null ? model : new Anchor(model);
};
Anchor.prototype = {
worksheet: null,
get col() {
return this.nativeCol + Math.min(this.colWidth - 1, this.nativeColOff) / this.colWidth;
},
set col(v) {
if (v === this.col) return;
this.nativeCol = Math.floor(v);
this.nativeColOff = Math.floor((v - this.nativeCol) * this.colWidth);
},
get row() {
return this.nativeRow + Math.min(this.rowHeight - 1, this.nativeRowOff) / this.rowHeight;
},
set row(v) {
if (v === this.row) return;
this.nativeRow = Math.floor(v);
this.nativeRowOff = Math.floor((v - this.nativeRow) * this.rowHeight);
},
get colWidth() {
return this.worksheet && this.worksheet.getColumn(this.nativeCol + 1) && this.worksheet.getColumn(this.nativeCol + 1).isCustomWidth ? Math.floor(this.worksheet.getColumn(this.nativeCol + 1).width * 10000) : 640000;
},
get rowHeight() {
return this.worksheet && this.worksheet.getRow(this.nativeRow + 1) && this.worksheet.getRow(this.nativeRow + 1).height ? Math.floor(this.worksheet.getRow(this.nativeRow + 1).height * 10000) : 180000;
}
};
//# sourceMappingURL=anchor.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../lib/doc/anchor.js"],"names":["Anchor","module","exports","model","nativeCol","nativeColOff","nativeRow","nativeRowOff","col","row","asInstance","prototype","worksheet","Math","min","colWidth","v","floor","rowHeight","getColumn","isCustomWidth","width","getRow","height"],"mappings":"AAAA;;AAEA,IAAIA,SAASC,OAAOC,OAAP,GAAiB,YAAsB;AAAA,MAAZC,KAAY,uEAAJ,EAAI;;AAClD,OAAKC,SAAL,GAAiBD,MAAMC,SAAN,IAAmB,CAApC;AACA,OAAKC,YAAL,GAAoBF,MAAME,YAAN,IAAsB,CAA1C;AACA,OAAKC,SAAL,GAAiBH,MAAMG,SAAN,IAAmB,CAApC;AACA,OAAKC,YAAL,GAAoBJ,MAAMI,YAAN,IAAsB,CAA1C;;AAEA,MAAIJ,MAAMK,GAAV,EAAe;AACb,SAAKA,GAAL,GAAWL,MAAMK,GAAjB;AACD;;AAED,MAAIL,MAAMM,GAAV,EAAe;AACb,SAAKA,GAAL,GAAWN,MAAMM,GAAjB;AACD;AACF,CAbD;;AAeAT,OAAOU,UAAP,GAAoB,UAAUP,KAAV,EAAiB;AACnC,SAAOA,iBAAiBH,MAAjB,IAA2BG,SAAS,IAApC,GAA2CA,KAA3C,GAAmD,IAAIH,MAAJ,CAAWG,KAAX,CAA1D;AACD,CAFD;;AAIAH,OAAOW,SAAP,GAAmB;AACjBC,aAAW,IADM;AAEjB,MAAIJ,GAAJ,GAAU;AACR,WAAO,KAAKJ,SAAL,GAAiBS,KAAKC,GAAL,CAAS,KAAKC,QAAL,GAAgB,CAAzB,EAA4B,KAAKV,YAAjC,IAAiD,KAAKU,QAA9E;AACD,GAJgB;AAKjB,MAAIP,GAAJ,CAAQQ,CAAR,EAAW;AACT,QAAIA,MAAM,KAAKR,GAAf,EAAoB;AACpB,SAAKJ,SAAL,GAAiBS,KAAKI,KAAL,CAAWD,CAAX,CAAjB;AACA,SAAKX,YAAL,GAAoBQ,KAAKI,KAAL,CAAW,CAACD,IAAI,KAAKZ,SAAV,IAAuB,KAAKW,QAAvC,CAApB;AACD,GATgB;AAUjB,MAAIN,GAAJ,GAAU;AACR,WAAO,KAAKH,SAAL,GAAiBO,KAAKC,GAAL,CAAS,KAAKI,SAAL,GAAiB,CAA1B,EAA6B,KAAKX,YAAlC,IAAkD,KAAKW,SAA/E;AACD,GAZgB;AAajB,MAAIT,GAAJ,CAAQO,CAAR,EAAW;AACT,QAAIA,MAAM,KAAKP,GAAf,EAAoB;AACpB,SAAKH,SAAL,GAAiBO,KAAKI,KAAL,CAAWD,CAAX,CAAjB;AACA,SAAKT,YAAL,GAAoBM,KAAKI,KAAL,CAAW,CAACD,IAAI,KAAKV,SAAV,IAAuB,KAAKY,SAAvC,CAApB;AACD,GAjBgB;AAkBjB,MAAIH,QAAJ,GAAe;AACb,WAAO,KAAKH,SAAL,IAAkB,KAAKA,SAAL,CAAeO,SAAf,CAAyB,KAAKf,SAAL,GAAiB,CAA1C,CAAlB,IAAkE,KAAKQ,SAAL,CAAeO,SAAf,CAAyB,KAAKf,SAAL,GAAiB,CAA1C,EAA6CgB,aAA/G,GACLP,KAAKI,KAAL,CAAW,KAAKL,SAAL,CAAeO,SAAf,CAAyB,KAAKf,SAAL,GAAiB,CAA1C,EAA6CiB,KAA7C,GAAqD,KAAhE,CADK,GAEL,MAFF;AAGD,GAtBgB;AAuBjB,MAAIH,SAAJ,GAAgB;AACd,WAAO,KAAKN,SAAL,IAAkB,KAAKA,SAAL,CAAeU,MAAf,CAAsB,KAAKhB,SAAL,GAAiB,CAAvC,CAAlB,IAA+D,KAAKM,SAAL,CAAeU,MAAf,CAAsB,KAAKhB,SAAL,GAAiB,CAAvC,EAA0CiB,MAAzG,GACLV,KAAKI,KAAL,CAAW,KAAKL,SAAL,CAAeU,MAAf,CAAsB,KAAKhB,SAAL,GAAiB,CAAvC,EAA0CiB,MAA1C,GAAmD,KAA9D,CADK,GAEL,MAFF;AAGD;AA3BgB,CAAnB","file":"anchor.js","sourcesContent":["'use strict';\n\nvar Anchor = module.exports = function (model = {}) {\n this.nativeCol = model.nativeCol || 0;\n this.nativeColOff = model.nativeColOff || 0;\n this.nativeRow = model.nativeRow || 0;\n this.nativeRowOff = model.nativeRowOff || 0;\n\n if (model.col) {\n this.col = model.col;\n }\n\n if (model.row) {\n this.row = model.row;\n }\n};\n\nAnchor.asInstance = function (model) {\n return model instanceof Anchor || model == null ? model : new Anchor(model);\n};\n\nAnchor.prototype = {\n worksheet: null,\n get col() {\n return this.nativeCol + Math.min(this.colWidth - 1, this.nativeColOff) / this.colWidth;\n },\n set col(v) {\n if (v === this.col) return;\n this.nativeCol = Math.floor(v);\n this.nativeColOff = Math.floor((v - this.nativeCol) * this.colWidth);\n },\n get row() {\n return this.nativeRow + Math.min(this.rowHeight - 1, this.nativeRowOff) / this.rowHeight;\n },\n set row(v) {\n if (v === this.row) return;\n this.nativeRow = Math.floor(v);\n this.nativeRowOff = Math.floor((v - this.nativeRow) * this.rowHeight);\n },\n get colWidth() {\n return this.worksheet && this.worksheet.getColumn(this.nativeCol + 1) && this.worksheet.getColumn(this.nativeCol + 1).isCustomWidth ?\n Math.floor(this.worksheet.getColumn(this.nativeCol + 1).width * 10000) :\n 640000;\n },\n get rowHeight() {\n return this.worksheet && this.worksheet.getRow(this.nativeRow + 1) && this.worksheet.getRow(this.nativeRow + 1).height ?\n Math.floor(this.worksheet.getRow(this.nativeRow + 1).height * 10000) :\n 180000;\n }\n};\n"]}

891
src/plugins/exceljs/dist/es5/doc/cell.js vendored Normal file
View File

@@ -0,0 +1,891 @@
'use strict';
var colCache = require('../utils/col-cache');
var _ = require('../utils/under-dash');
var Enums = require('./enums');
var _require = require('../utils/shared-formula'),
slideFormula = _require.slideFormula;
// Cell requirements
// Operate inside a worksheet
// Store and retrieve a value with a range of types: text, number, date, hyperlink, reference, formula, etc.
// Manage/use and manipulate cell format either as local to cell or inherited from column or row.
var Cell = module.exports = function (row, column, address) {
if (!row || !column) {
throw new Error('A Cell needs a Row');
}
this._row = row;
this._column = column;
colCache.validateAddress(address);
this._address = address;
// TODO: lazy evaluation of this._value
this._value = Value.create(Cell.Types.Null, this);
this.style = this._mergeStyle(row.style, column.style, {});
this._mergeCount = 0;
};
Cell.Types = Enums.ValueType;
Cell.prototype = {
get worksheet() {
return this._row.worksheet;
},
get workbook() {
return this._row.worksheet.workbook;
},
// help GC by removing cyclic (and other) references
destroy: function destroy() {
delete this.style;
delete this._value;
delete this._row;
delete this._column;
delete this._address;
},
// =========================================================================
// Styles stuff
get numFmt() {
return this.style.numFmt;
},
set numFmt(value) {
this.style.numFmt = value;
},
get font() {
return this.style.font;
},
set font(value) {
this.style.font = value;
},
get alignment() {
return this.style.alignment;
},
set alignment(value) {
this.style.alignment = value;
},
get border() {
return this.style.border;
},
set border(value) {
this.style.border = value;
},
get fill() {
return this.style.fill;
},
set fill(value) {
this.style.fill = value;
},
_mergeStyle: function _mergeStyle(rowStyle, colStyle, style) {
var numFmt = rowStyle && rowStyle.numFmt || colStyle && colStyle.numFmt;
if (numFmt) style.numFmt = numFmt;
var font = rowStyle && rowStyle.font || colStyle && colStyle.font;
if (font) style.font = font;
var alignment = rowStyle && rowStyle.alignment || colStyle && colStyle.alignment;
if (alignment) style.alignment = alignment;
var border = rowStyle && rowStyle.border || colStyle && colStyle.border;
if (border) style.border = border;
var fill = rowStyle && rowStyle.fill || colStyle && colStyle.fill;
if (fill) style.fill = fill;
return style;
},
// =========================================================================
// return the address for this cell
get address() {
return this._address;
},
get row() {
return this._row.number;
},
get col() {
return this._column.number;
},
get $col$row() {
return '$' + this._column.letter + '$' + this.row;
},
// =========================================================================
// Value stuff
get type() {
return this._value.type;
},
get effectiveType() {
return this._value.effectiveType;
},
toCsvString: function toCsvString() {
return this._value.toCsvString();
},
// =========================================================================
// Merge stuff
addMergeRef: function addMergeRef() {
this._mergeCount++;
},
releaseMergeRef: function releaseMergeRef() {
this._mergeCount--;
},
get isMerged() {
return this._mergeCount > 0 || this.type === Cell.Types.Merge;
},
merge: function merge(master) {
this._value.release();
this._value = Value.create(Cell.Types.Merge, this, master);
this.style = master.style;
},
unmerge: function unmerge() {
if (this.type === Cell.Types.Merge) {
this._value.release();
this._value = Value.create(Cell.Types.Null, this);
this.style = this._mergeStyle(this._row.style, this._column.style, {});
}
},
isMergedTo: function isMergedTo(master) {
if (this._value.type !== Cell.Types.Merge) return false;
return this._value.isMergedTo(master);
},
get master() {
if (this.type === Cell.Types.Merge) {
return this._value.master;
}
return this; // an unmerged cell is its own master
},
get isHyperlink() {
return this._value.type === Cell.Types.Hyperlink;
},
get hyperlink() {
return this._value.hyperlink;
},
// return the value
get value() {
return this._value.value;
},
// set the value - can be number, string or raw
set value(v) {
// special case - merge cells set their master's value
if (this.type === Cell.Types.Merge) {
this._value.master.value = v;
return;
}
this._value.release();
// assign value
this._value = Value.create(Value.getType(v), this, v);
},
get text() {
return this._value.toString();
},
get html() {
return _.escapeHtml(this.text);
},
toString: function toString() {
return this.text;
},
_upgradeToHyperlink: function _upgradeToHyperlink(hyperlink) {
// if this cell is a string, turn it into a Hyperlink
if (this.type === Cell.Types.String) {
this._value = Value.create(Cell.Types.Hyperlink, this, {
text: this._value.value,
hyperlink: hyperlink
});
}
},
// =========================================================================
// Formula stuff
get formula() {
return this._value.formula;
},
get result() {
return this._value.result;
},
get formulaType() {
return this._value.formulaType;
},
// =========================================================================
// Name stuff
get fullAddress() {
var worksheet = this._row.worksheet;
return {
sheetName: worksheet.name,
address: this.address,
row: this.row,
col: this.col
};
},
get name() {
return this.names[0];
},
set name(value) {
this.names = [value];
},
get names() {
return this.workbook.definedNames.getNamesEx(this.fullAddress);
},
set names(value) {
var self = this;
var definedNames = this.workbook.definedNames;
this.workbook.definedNames.removeAllNames(self.fullAddress);
value.forEach(function (name) {
definedNames.addEx(self.fullAddress, name);
});
},
addName: function addName(name) {
this.workbook.definedNames.addEx(this.fullAddress, name);
},
removeName: function removeName(name) {
this.workbook.definedNames.removeEx(this.fullAddress, name);
},
removeAllNames: function removeAllNames() {
this.workbook.definedNames.removeAllNames(this.fullAddress);
},
// =========================================================================
// Data Validation stuff
get _dataValidations() {
return this.worksheet.dataValidations;
},
get dataValidation() {
return this._dataValidations.find(this.address);
},
set dataValidation(value) {
this._dataValidations.add(this.address, value);
},
// =========================================================================
// Model stuff
get model() {
var model = this._value.model;
model.style = this.style;
return model;
},
set model(value) {
this._value.release();
this._value = Value.create(value.type, this);
this._value.model = value;
if (value.style) {
this.style = value.style;
} else {
this.style = {};
}
}
};
// =============================================================================
// Internal Value Types
var NullValue = function NullValue(cell) {
this.model = {
address: cell.address,
type: Cell.Types.Null
};
};
NullValue.prototype = {
get value() {
return null;
},
set value(value) {
// nothing to do
},
get type() {
return Cell.Types.Null;
},
get effectiveType() {
return Cell.Types.Null;
},
get address() {
return this.model.address;
},
set address(value) {
this.model.address = value;
},
toCsvString: function toCsvString() {
return '';
},
release: function release() {},
toString: function toString() {
return '';
}
};
var NumberValue = function NumberValue(cell, value) {
this.model = {
address: cell.address,
type: Cell.Types.Number,
value: value
};
};
NumberValue.prototype = {
get value() {
return this.model.value;
},
set value(value) {
this.model.value = value;
},
get type() {
return Cell.Types.Number;
},
get effectiveType() {
return Cell.Types.Number;
},
get address() {
return this.model.address;
},
set address(value) {
this.model.address = value;
},
toCsvString: function toCsvString() {
return '' + this.model.value;
},
release: function release() {},
toString: function toString() {
return this.model.value.toString();
}
};
var StringValue = function StringValue(cell, value) {
this.model = {
address: cell.address,
type: Cell.Types.String,
value: value
};
};
StringValue.prototype = {
get value() {
return this.model.value;
},
set value(value) {
this.model.value = value;
},
get type() {
return Cell.Types.String;
},
get effectiveType() {
return Cell.Types.String;
},
get address() {
return this.model.address;
},
set address(value) {
this.model.address = value;
},
toCsvString: function toCsvString() {
return '"' + this.model.value.replace(/"/g, '""') + '"';
},
release: function release() {},
toString: function toString() {
return this.model.value;
}
};
var RichTextValue = function RichTextValue(cell, value) {
this.model = {
address: cell.address,
type: Cell.Types.String,
value: value
};
};
RichTextValue.prototype = {
get value() {
return this.model.value;
},
set value(value) {
this.model.value = value;
},
toString: function toString() {
return this.model.value.richText.map(function (t) {
return t.text;
}).join('');
},
get type() {
return Cell.Types.RichText;
},
get effectiveType() {
return Cell.Types.RichText;
},
get address() {
return this.model.address;
},
set address(value) {
this.model.address = value;
},
toCsvString: function toCsvString() {
return '"' + this.text.replace(/"/g, '""') + '"';
},
release: function release() {}
};
var DateValue = function DateValue(cell, value) {
this.model = {
address: cell.address,
type: Cell.Types.Date,
value: value
};
};
DateValue.prototype = {
get value() {
return this.model.value;
},
set value(value) {
this.model.value = value;
},
get type() {
return Cell.Types.Date;
},
get effectiveType() {
return Cell.Types.Date;
},
get address() {
return this.model.address;
},
set address(value) {
this.model.address = value;
},
toCsvString: function toCsvString() {
return this.model.value.toISOString();
},
release: function release() {},
toString: function toString() {
return this.model.value.toString();
}
};
var HyperlinkValue = function HyperlinkValue(cell, value) {
this.model = Object.assign({
address: cell.address,
type: Cell.Types.Hyperlink,
text: value ? value.text : undefined,
hyperlink: value ? value.hyperlink : undefined
}, value && value.tooltip ? { tooltip: value.tooltip } : {});
};
HyperlinkValue.prototype = {
get value() {
return Object.assign({
text: this.model.text,
hyperlink: this.model.hyperlink
}, this.model.tooltip ? { tooltip: this.model.tooltip } : {});
},
set value(value) {
this.model = Object.assign({
text: value.text,
hyperlink: value.hyperlink
}, value && value.tooltip ? { tooltip: value.tooltip } : {});
},
get text() {
return this.model.text;
},
set text(value) {
this.model.text = value;
}, /*
get tooltip() {
return this.model.tooltip;
},
set tooltip(value) {
this.model.tooltip = value;
},*/
get hyperlink() {
return this.model.hyperlink;
},
set hyperlink(value) {
this.model.hyperlink = value;
},
get type() {
return Cell.Types.Hyperlink;
},
get effectiveType() {
return Cell.Types.Hyperlink;
},
get address() {
return this.model.address;
},
set address(value) {
this.model.address = value;
},
toCsvString: function toCsvString() {
return this.model.hyperlink;
},
release: function release() {},
toString: function toString() {
return this.model.text;
}
};
var MergeValue = function MergeValue(cell, master) {
this.model = {
address: cell.address,
type: Cell.Types.Merge,
master: master ? master.address : undefined
};
this._master = master;
if (master) {
master.addMergeRef();
}
};
MergeValue.prototype = {
get value() {
return this._master.value;
},
set value(value) {
if (value instanceof Cell) {
if (this._master) {
this._master.releaseMergeRef();
}
value.addMergeRef();
this._master = value;
} else {
this._master.value = value;
}
},
isMergedTo: function isMergedTo(master) {
return master === this._master;
},
get master() {
return this._master;
},
get type() {
return Cell.Types.Merge;
},
get effectiveType() {
return this._master.effectiveType;
},
get address() {
return this.model.address;
},
set address(value) {
this.model.address = value;
},
toCsvString: function toCsvString() {
return '';
},
release: function release() {
this._master.releaseMergeRef();
},
toString: function toString() {
return this.value.toString();
}
};
var FormulaValue = function FormulaValue(cell, value) {
this.cell = cell;
this.model = {
address: cell.address,
type: Cell.Types.Formula,
formula: value ? value.formula : undefined,
sharedFormula: value ? value.sharedFormula : undefined,
result: value ? value.result : undefined
};
};
FormulaValue.prototype = {
get value() {
return this.model.formula ? {
formula: this.model.formula,
result: this.model.result
} : {
sharedFormula: this.model.sharedFormula,
result: this.model.result
};
},
set value(value) {
this.model.formula = value.formula;
this.model.sharedFormula = value.sharedFormula;
this.model.result = value.result;
},
validate: function validate(value) {
switch (Value.getType(value)) {
case Cell.Types.Null:
case Cell.Types.String:
case Cell.Types.Number:
case Cell.Types.Date:
break;
case Cell.Types.Hyperlink:
case Cell.Types.Formula:
default:
throw new Error('Cannot process that type of result value');
}
},
get dependencies() {
// find all the ranges and cells mentioned in the formula
var ranges = this.formula.match(/([a-zA-Z0-9]+!)?[A-Z]{1,3}\d{1,4}:[A-Z]{1,3}\d{1,4}/g);
var cells = this.formula.replace(/([a-zA-Z0-9]+!)?[A-Z]{1,3}\d{1,4}:[A-Z]{1,3}\d{1,4}/g, '').match(/([a-zA-Z0-9]+!)?[A-Z]{1,3}\d{1,4}/g);
return {
ranges: ranges,
cells: cells
};
},
get formula() {
return this.model.formula || this._getTranslatedFormula();
},
set formula(value) {
this.model.formula = value;
},
get formulaType() {
if (this.model.formula) {
return Enums.FormulaType.Master;
}
if (this.model.sharedFormula) {
return Enums.FormulaType.Shared;
}
return Enums.FormulaType.None;
},
get result() {
return this.model.result;
},
set result(value) {
this.model.result = value;
},
get type() {
return Cell.Types.Formula;
},
get effectiveType() {
var v = this.model.result;
if (v === null || v === undefined) {
return Enums.ValueType.Null;
} else if (v instanceof String || typeof v === 'string') {
return Enums.ValueType.String;
} else if (typeof v === 'number') {
return Enums.ValueType.Number;
} else if (v instanceof Date) {
return Enums.ValueType.Date;
} else if (v.text && v.hyperlink) {
return Enums.ValueType.Hyperlink;
} else if (v.formula) {
return Enums.ValueType.Formula;
}
return Enums.ValueType.Null;
},
get address() {
return this.model.address;
},
set address(value) {
this.model.address = value;
},
_getTranslatedFormula: function _getTranslatedFormula() {
if (!this._translatedFormula && this.model.sharedFormula) {
var worksheet = this.cell.worksheet;
var master = worksheet.findCell(this.model.sharedFormula);
this._translatedFormula = master && slideFormula(master.formula, master.address, this.model.address);
}
return this._translatedFormula;
},
toCsvString: function toCsvString() {
return '' + (this.model.result || '');
},
release: function release() {},
toString: function toString() {
return this.model.result ? this.model.result.toString() : '';
}
};
var SharedStringValue = function SharedStringValue(cell, value) {
this.model = {
address: cell.address,
type: Cell.Types.SharedString,
value: value
};
};
SharedStringValue.prototype = {
get value() {
return this.model.value;
},
set value(value) {
this.model.value = value;
},
get type() {
return Cell.Types.SharedString;
},
get effectiveType() {
return Cell.Types.SharedString;
},
get address() {
return this.model.address;
},
set address(value) {
this.model.address = value;
},
toCsvString: function toCsvString() {
return '' + this.model.value;
},
release: function release() {},
toString: function toString() {
return this.model.value.toString();
}
};
var BooleanValue = function BooleanValue(cell, value) {
this.model = {
address: cell.address,
type: Cell.Types.Boolean,
value: value
};
};
BooleanValue.prototype = {
get value() {
return this.model.value;
},
set value(value) {
this.model.value = value;
},
get type() {
return Cell.Types.Boolean;
},
get effectiveType() {
return Cell.Types.Boolean;
},
get address() {
return this.model.address;
},
set address(value) {
this.model.address = value;
},
toCsvString: function toCsvString() {
return this.model.value ? 1 : 0;
},
release: function release() {},
toString: function toString() {
return this.model.value.toString();
}
};
var ErrorValue = function ErrorValue(cell, value) {
this.model = {
address: cell.address,
type: Cell.Types.Error,
value: value
};
};
ErrorValue.prototype = {
get value() {
return this.model.value;
},
set value(value) {
this.model.value = value;
},
get type() {
return Cell.Types.Error;
},
get effectiveType() {
return Cell.Types.Error;
},
get address() {
return this.model.address;
},
set address(value) {
this.model.address = value;
},
toCsvString: function toCsvString() {
return this.toString();
},
release: function release() {},
toString: function toString() {
return this.model.value.error.toString();
}
};
var JSONValue = function JSONValue(cell, value) {
this.model = {
address: cell.address,
type: Cell.Types.String,
value: JSON.stringify(value),
rawValue: value
};
};
JSONValue.prototype = {
get value() {
return this.model.rawValue;
},
set value(value) {
this.model.rawValue = value;
this.model.value = JSON.stringify(value);
},
get type() {
return Cell.Types.String;
},
get effectiveType() {
return Cell.Types.String;
},
get address() {
return this.model.address;
},
set address(value) {
this.model.address = value;
},
toCsvString: function toCsvString() {
return this.model.value;
},
release: function release() {},
toString: function toString() {
return this.model.value;
}
};
// Value is a place to hold common static Value type functions
var Value = {
getType: function getType(value) {
if (value === null || value === undefined) {
return Cell.Types.Null;
} else if (value instanceof String || typeof value === 'string') {
return Cell.Types.String;
} else if (typeof value === 'number') {
return Cell.Types.Number;
} else if (typeof value === 'boolean') {
return Cell.Types.Boolean;
} else if (value instanceof Date) {
return Cell.Types.Date;
} else if (value.text && value.hyperlink) {
return Cell.Types.Hyperlink;
} else if (value.formula || value.sharedFormula) {
return Cell.Types.Formula;
} else if (value.richText) {
return Cell.Types.RichText;
} else if (value.sharedString) {
return Cell.Types.SharedString;
} else if (value.error) {
return Cell.Types.Error;
}
return Cell.Types.JSON;
},
// map valueType to constructor
types: [{ t: Cell.Types.Null, f: NullValue }, { t: Cell.Types.Number, f: NumberValue }, { t: Cell.Types.String, f: StringValue }, { t: Cell.Types.Date, f: DateValue }, { t: Cell.Types.Hyperlink, f: HyperlinkValue }, { t: Cell.Types.Formula, f: FormulaValue }, { t: Cell.Types.Merge, f: MergeValue }, { t: Cell.Types.JSON, f: JSONValue }, { t: Cell.Types.SharedString, f: SharedStringValue }, { t: Cell.Types.RichText, f: RichTextValue }, { t: Cell.Types.Boolean, f: BooleanValue }, { t: Cell.Types.Error, f: ErrorValue }].reduce(function (p, t) {
p[t.t] = t.f;return p;
}, []),
create: function create(type, cell, value) {
var T = this.types[type];
if (!T) {
throw new Error('Could not create Value of type ' + type);
}
return new T(cell, value);
}
};
//# sourceMappingURL=cell.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,271 @@
'use strict';
var _ = require('../utils/under-dash');
var Enums = require('./enums');
var colCache = require('../utils/col-cache');
// Column defines the column properties for 1 column.
// This includes header rows, widths, key, (style), etc.
// Worksheet will condense the columns as appropriate during serialization
var Column = module.exports = function (worksheet, number, defn) {
this._worksheet = worksheet;
this._number = number;
if (defn !== false) {
// sometimes defn will follow
this.defn = defn;
}
};
Column.prototype = {
get number() {
return this._number;
},
get worksheet() {
return this._worksheet;
},
get letter() {
return colCache.n2l(this._number);
},
get isCustomWidth() {
return this.width !== undefined && this.width !== 8;
},
get defn() {
return {
header: this._header,
key: this.key,
width: this.width,
style: this.style,
hidden: this.hidden,
outlineLevel: this.outlineLevel
};
},
set defn(value) {
if (value) {
this.key = value.key;
this.width = value.width;
this.outlineLevel = value.outlineLevel;
if (value.style) {
this.style = value.style;
} else {
this.style = {};
}
// headers must be set after style
this.header = value.header;
this._hidden = !!value.hidden;
} else {
delete this._header;
delete this.key;
delete this.width;
this.style = {};
this.outlineLevel = 0;
}
},
get headers() {
return this._header && this._header instanceof Array ? this._header : [this._header];
},
get header() {
return this._header;
},
set header(value) {
var _this = this;
if (value !== undefined) {
this._header = value;
this.headers.forEach(function (text, index) {
_this._worksheet.getCell(index + 1, _this.number).value = text;
});
} else {
this._header = undefined;
}
},
get key() {
return this._key;
},
set key(value) {
var column = this._key && this._worksheet.getColumnKey(this._key);
if (column === this) {
this._worksheet.deleteColumnKey(this._key);
}
this._key = value;
if (value) {
this._worksheet.setColumnKey(this._key, this);
}
},
get hidden() {
return !!this._hidden;
},
set hidden(value) {
this._hidden = value;
},
get outlineLevel() {
return this._outlineLevel || 0;
},
set outlineLevel(value) {
this._outlineLevel = value;
},
get collapsed() {
return !!(this._outlineLevel && this._outlineLevel >= this._worksheet.properties.outlineLevelCol);
},
toString: function toString() {
return JSON.stringify({
key: this.key,
width: this.width,
headers: this.headers.length ? this.headers : undefined
});
},
equivalentTo: function equivalentTo(other) {
return this.width === other.width && this.hidden === other.hidden && this.outlineLevel === other.outlineLevel && _.isEqual(this.style, other.style);
},
get isDefault() {
if (this.isCustomWidth) {
return false;
}
if (this.hidden) {
return false;
}
if (this.outlineLevel) {
return false;
}
var s = this.style;
if (s && (s.font || s.numFmt || s.alignment || s.border || s.fill)) {
return false;
}
return true;
},
get headerCount() {
return this.headers.length;
},
eachCell: function eachCell(options, iteratee) {
var colNumber = this.number;
if (!iteratee) {
iteratee = options;
options = null;
}
this._worksheet.eachRow(options, function (row, rowNumber) {
iteratee(row.getCell(colNumber), rowNumber);
});
},
get values() {
var v = [];
this.eachCell(function (cell, rowNumber) {
if (cell && cell.type !== Enums.ValueType.Null) {
v[rowNumber] = cell.value;
}
});
return v;
},
set values(v) {
var _this2 = this;
if (!v) {
return;
}
var colNumber = this.number;
var offset = 0;
if (v.hasOwnProperty('0')) {
// assume contiguous array, start at row 1
offset = 1;
}
v.forEach(function (value, index) {
_this2._worksheet.getCell(index + offset, colNumber).value = value;
});
},
// =========================================================================
// styles
_applyStyle: function _applyStyle(name, value) {
this.style[name] = value;
this.eachCell(function (cell) {
cell[name] = value;
});
return value;
},
get numFmt() {
return this.style.numFmt;
},
set numFmt(value) {
this._applyStyle('numFmt', value);
},
get font() {
return this.style.font;
},
set font(value) {
this._applyStyle('font', value);
},
get alignment() {
return this.style.alignment;
},
set alignment(value) {
this._applyStyle('alignment', value);
},
get border() {
return this.style.border;
},
set border(value) {
this._applyStyle('border', value);
},
get fill() {
return this.style.fill;
},
set fill(value) {
this._applyStyle('fill', value);
}
};
// =============================================================================
// static functions
Column.toModel = function (columns) {
// Convert array of Column into compressed list cols
var cols = [];
var col = null;
if (columns) {
columns.forEach(function (column, index) {
if (column.isDefault) {
if (col) {
col = null;
}
} else if (!col || !column.equivalentTo(col)) {
col = {
min: index + 1,
max: index + 1,
width: column.width,
style: column.style,
isCustomWidth: column.isCustomWidth,
hidden: column.hidden,
outlineLevel: column.outlineLevel,
collapsed: column.collapsed
};
cols.push(col);
} else {
col.max = index + 1;
}
});
}
return cols.length ? cols : undefined;
};
Column.fromModel = function (worksheet, cols) {
cols = cols || [];
var columns = [];
var count = 1;
var index = 0;
while (index < cols.length) {
var col = cols[index++];
while (count < col.min) {
columns.push(new Column(worksheet, count++));
}
while (count <= col.max) {
columns.push(new Column(worksheet, count++, col));
}
}
return columns.length ? columns : null;
};
//# sourceMappingURL=column.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,18 @@
'use strict';
var DataValidations = module.exports = function (model) {
this.model = model || {};
};
DataValidations.prototype = {
add: function add(address, validation) {
return this.model[address] = validation;
},
find: function find(address) {
return this.model[address];
},
remove: function remove(address) {
this.model[address] = undefined;
}
};
//# sourceMappingURL=data-validations.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../lib/doc/data-validations.js"],"names":["DataValidations","module","exports","model","prototype","add","address","validation","find","remove","undefined"],"mappings":"AAAA;;AAEA,IAAIA,kBAAkBC,OAAOC,OAAP,GAAiB,UAASC,KAAT,EAAgB;AACrD,OAAKA,KAAL,GAAaA,SAAS,EAAtB;AACD,CAFD;;AAIAH,gBAAgBI,SAAhB,GAA4B;AAC1BC,OAAK,aAASC,OAAT,EAAkBC,UAAlB,EAA8B;AACjC,WAAQ,KAAKJ,KAAL,CAAWG,OAAX,IAAsBC,UAA9B;AACD,GAHyB;AAI1BC,QAAM,cAASF,OAAT,EAAkB;AACtB,WAAO,KAAKH,KAAL,CAAWG,OAAX,CAAP;AACD,GANyB;AAO1BG,UAAQ,gBAASH,OAAT,EAAkB;AACxB,SAAKH,KAAL,CAAWG,OAAX,IAAsBI,SAAtB;AACD;AATyB,CAA5B","file":"data-validations.js","sourcesContent":["'use strict';\n\nvar DataValidations = module.exports = function(model) {\n this.model = model || {};\n};\n\nDataValidations.prototype = {\n add: function(address, validation) {\n return (this.model[address] = validation);\n },\n find: function(address) {\n return this.model[address];\n },\n remove: function(address) {\n this.model[address] = undefined;\n }\n};\n\n"]}

View File

@@ -0,0 +1,166 @@
'use strict';
var _ = require('../utils/under-dash');
var colCache = require('../utils/col-cache');
var CellMatrix = require('../utils/cell-matrix');
var Range = require('./range');
var rangeRegexp = /[$](\w+)[$](\d+)(:[$](\w+)[$](\d+))?/;
var DefinedNames = module.exports = function () {
this.matrixMap = {};
};
DefinedNames.prototype = {
getMatrix: function getMatrix(name) {
return this.matrixMap[name] || (this.matrixMap[name] = new CellMatrix());
},
// add a name to a cell. locStr in the form SheetName!$col$row or SheetName!$c1$r1:$c2:$r2
add: function add(locStr, name) {
var location = colCache.decodeEx(locStr);
this.addEx(location, name);
},
addEx: function addEx(location, name) {
var matrix = this.getMatrix(name);
if (location.top) {
for (var col = location.left; col <= location.right; col++) {
for (var row = location.top; row <= location.bottom; row++) {
var address = {
sheetName: location.sheetName,
address: colCache.n2l(col) + row,
row: row,
col: col
};
matrix.addCellEx(address);
}
}
} else {
matrix.addCellEx(location);
}
},
remove: function remove(locStr, name) {
var location = colCache.decodeEx(locStr);
this.removeEx(location, name);
},
removeEx: function removeEx(location, name) {
var matrix = this.getMatrix(name);
matrix.removeCellEx(location);
},
removeAllNames: function removeAllNames(location) {
_.each(this.matrixMap, function (matrix) {
matrix.removeCellEx(location);
});
},
forEach: function forEach(callback) {
_.each(this.matrixMap, function (matrix, name) {
matrix.forEach(function (cell) {
callback(name, cell);
});
});
},
// get all the names of a cell
getNames: function getNames(addressStr) {
return this.getNamesEx(colCache.decodeEx(addressStr));
},
getNamesEx: function getNamesEx(address) {
return _.map(this.matrixMap, function (matrix, name) {
return matrix.findCellEx(address) && name;
}).filter(Boolean);
},
_explore: function _explore(matrix, cell) {
cell.mark = false;
var sheetName = cell.sheetName;
var range = new Range(cell.row, cell.col, cell.row, cell.col, sheetName);
var x, y;
// grow vertical - only one col to worry about
function vGrow(yy, edge) {
var c = matrix.findCellAt(sheetName, yy, cell.col);
if (!c || !c.mark) {
return false;
}
range[edge] = yy;
c.mark = false;
return true;
}
for (y = cell.row - 1; vGrow(y, 'top'); y--) {}
for (y = cell.row + 1; vGrow(y, 'bottom'); y++) {}
// grow horizontal - ensure all rows can grow
function hGrow(xx, edge) {
var c,
cells = [];
for (y = range.top; y <= range.bottom; y++) {
c = matrix.findCellAt(sheetName, y, xx);
if (c && c.mark) {
cells.push(c);
} else {
return false;
}
}
range[edge] = xx;
for (var i = 0; i < cells.length; i++) {
cells[i].mark = false;
}
return true;
}
for (x = cell.col - 1; hGrow(x, 'left'); x--) {}
for (x = cell.col + 1; hGrow(x, 'right'); x++) {}
return range;
},
getRanges: function getRanges(name, matrix) {
var _this = this;
matrix = matrix || this.matrixMap[name];
if (!matrix) {
return { name: name, ranges: [] };
}
// mark and sweep!
matrix.forEach(function (cell) {
cell.mark = true;
});
var ranges = matrix.map(function (cell) {
return cell.mark && _this._explore(matrix, cell);
}).filter(Boolean).map(function (range) {
return range.$shortRange;
});
return {
name: name, ranges: ranges
};
},
get model() {
var self = this;
// To get names per cell - just iterate over all names finding cells if they exist
return _.map(this.matrixMap, function (matrix, name) {
return self.getRanges(name, matrix);
}).filter(function (definedName) {
return definedName.ranges.length;
});
},
set model(value) {
// value is [ { name, ranges }, ... ]
var matrixMap = this.matrixMap = {};
value.forEach(function (definedName) {
var matrix = matrixMap[definedName.name] = new CellMatrix();
definedName.ranges.forEach(function (rangeStr) {
if (rangeRegexp.test(rangeStr.split('!').pop() || '')) {
matrix.addCell(rangeStr);
}
});
});
}
};
//# sourceMappingURL=defined-names.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,49 @@
'use strict';
module.exports = {
ValueType: {
Null: 0,
Merge: 1,
Number: 2,
String: 3,
Date: 4,
Hyperlink: 5,
Formula: 6,
SharedString: 7,
RichText: 8,
Boolean: 9,
Error: 10
},
FormulaType: {
None: 0,
Master: 1,
Shared: 2
},
RelationshipType: {
None: 0,
OfficeDocument: 1,
Worksheet: 2,
CalcChain: 3,
SharedStrings: 4,
Styles: 5,
Theme: 6,
Hyperlink: 7
},
DocumentType: {
Xlsx: 1
},
ReadingOrder: {
LeftToRight: 1,
RightToLeft: 2
},
ErrorValue: {
NotApplicable: '#N/A',
Ref: '#REF!',
Name: '#NAME?',
DivZero: '#DIV/0!',
Null: '#NULL!',
Value: '#VALUE!',
Num: '#NUM!'
}
};
//# sourceMappingURL=enums.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../lib/doc/enums.js"],"names":["module","exports","ValueType","Null","Merge","Number","String","Date","Hyperlink","Formula","SharedString","RichText","Boolean","Error","FormulaType","None","Master","Shared","RelationshipType","OfficeDocument","Worksheet","CalcChain","SharedStrings","Styles","Theme","DocumentType","Xlsx","ReadingOrder","LeftToRight","RightToLeft","ErrorValue","NotApplicable","Ref","Name","DivZero","Value","Num"],"mappings":"AAAA;;AAEAA,OAAOC,OAAP,GAAiB;AACfC,aAAW;AACTC,UAAM,CADG;AAETC,WAAO,CAFE;AAGTC,YAAQ,CAHC;AAITC,YAAQ,CAJC;AAKTC,UAAM,CALG;AAMTC,eAAW,CANF;AAOTC,aAAS,CAPA;AAQTC,kBAAc,CARL;AASTC,cAAU,CATD;AAUTC,aAAS,CAVA;AAWTC,WAAO;AAXE,GADI;AAcfC,eAAa;AACXC,UAAM,CADK;AAEXC,YAAQ,CAFG;AAGXC,YAAQ;AAHG,GAdE;AAmBfC,oBAAkB;AAChBH,UAAM,CADU;AAEhBI,oBAAgB,CAFA;AAGhBC,eAAW,CAHK;AAIhBC,eAAW,CAJK;AAKhBC,mBAAe,CALC;AAMhBC,YAAQ,CANQ;AAOhBC,WAAO,CAPS;AAQhBhB,eAAW;AARK,GAnBH;AA6BfiB,gBAAc;AACZC,UAAM;AADM,GA7BC;AAgCfC,gBAAc;AACZC,iBAAa,CADD;AAEZC,iBAAa;AAFD,GAhCC;AAoCfC,cAAY;AACVC,mBAAe,MADL;AAEVC,SAAK,OAFK;AAGVC,UAAM,QAHI;AAIVC,aAAS,SAJC;AAKV/B,UAAM,QALI;AAMVgC,WAAO,SANG;AAOVC,SAAK;AAPK;AApCG,CAAjB","file":"enums.js","sourcesContent":["'use strict';\n\nmodule.exports = {\n ValueType: {\n Null: 0,\n Merge: 1,\n Number: 2,\n String: 3,\n Date: 4,\n Hyperlink: 5,\n Formula: 6,\n SharedString: 7,\n RichText: 8,\n Boolean: 9,\n Error: 10,\n },\n FormulaType: {\n None: 0,\n Master: 1,\n Shared: 2,\n },\n RelationshipType: {\n None: 0,\n OfficeDocument: 1,\n Worksheet: 2,\n CalcChain: 3,\n SharedStrings: 4,\n Styles: 5,\n Theme: 6,\n Hyperlink: 7,\n },\n DocumentType: {\n Xlsx: 1,\n },\n ReadingOrder: {\n LeftToRight: 1,\n RightToLeft: 2,\n },\n ErrorValue: {\n NotApplicable: '#N/A',\n Ref: '#REF!',\n Name: '#NAME?',\n DivZero: '#DIV/0!',\n Null: '#NULL!',\n Value: '#VALUE!',\n Num: '#NUM!',\n },\n};\n"]}

View File

@@ -0,0 +1,14 @@
'use strict';
var XLSX = require('./../xlsx/xlsx');
var ModelContainer = module.exports = function (model) {
this.model = model;
};
ModelContainer.prototype = {
get xlsx() {
return this._xlsx || (this._xlsx = new XLSX(this));
}
};
//# sourceMappingURL=modelcontainer.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../lib/doc/modelcontainer.js"],"names":["XLSX","require","ModelContainer","module","exports","model","prototype","xlsx","_xlsx"],"mappings":"AAAA;;AAEA,IAAIA,OAAOC,QAAQ,gBAAR,CAAX;;AAEA,IAAIC,iBAAiBC,OAAOC,OAAP,GAAiB,UAASC,KAAT,EAAgB;AACpD,OAAKA,KAAL,GAAaA,KAAb;AACD,CAFD;;AAKAH,eAAeI,SAAf,GAA2B;AACzB,MAAIC,IAAJ,GAAW;AACT,WAAO,KAAKC,KAAL,KAAe,KAAKA,KAAL,GAAa,IAAIR,IAAJ,CAAS,IAAT,CAA5B,CAAP;AACD;AAHwB,CAA3B","file":"modelcontainer.js","sourcesContent":["'use strict';\n\nvar XLSX = require('./../xlsx/xlsx');\n\nvar ModelContainer = module.exports = function(model) {\n this.model = model;\n};\n\n\nModelContainer.prototype = {\n get xlsx() {\n return this._xlsx || (this._xlsx = new XLSX(this));\n }\n};\n"]}

View File

@@ -0,0 +1,216 @@
'use strict';
var colCache = require('./../utils/col-cache');
// used by worksheet to calculate sheet dimensions
var Range = module.exports = function () {
this.decode(arguments);
};
Range.prototype = {
_set_tlbr: function _set_tlbr(t, l, b, r, s) {
this.model = {
top: Math.min(t, b),
left: Math.min(l, r),
bottom: Math.max(t, b),
right: Math.max(l, r),
sheetName: s
};
},
_set_tl_br: function _set_tl_br(tl, br, s) {
tl = colCache.decodeAddress(tl);
br = colCache.decodeAddress(br);
this._set_tlbr(tl.row, tl.col, br.row, br.col, s);
},
decode: function decode(argv) {
switch (argv.length) {
case 5:
// [t,l,b,r,s]
this._set_tlbr(argv[0], argv[1], argv[2], argv[3], argv[4]);
break;
case 4:
// [t,l,b,r]
this._set_tlbr(argv[0], argv[1], argv[2], argv[3]);
break;
case 3:
// [tl,br,s]
this._set_tl_br(argv[0], argv[1], argv[2]);
break;
case 2:
// [tl,br]
this._set_tl_br(argv[0], argv[1]);
break;
case 1:
var value = argv[0];
if (value instanceof Range) {
// copy constructor
this.model = {
top: value.model.top,
left: value.model.left,
bottom: value.model.bottom,
right: value.model.right,
sheetName: value.sheetName
};
} else if (value instanceof Array) {
// an arguments array
this.decode(value);
} else if (value.top && value.left && value.bottom && value.right) {
// a model
this.model = {
top: value.top,
left: value.left,
bottom: value.bottom,
right: value.right,
sheetName: value.sheetName
};
} else {
// [sheetName!]tl:br
var tlbr = colCache.decodeEx(value);
if (tlbr.top) {
this.model = {
top: tlbr.top,
left: tlbr.left,
bottom: tlbr.bottom,
right: tlbr.right,
sheetName: tlbr.sheetName
};
} else {
this.model = {
top: tlbr.row,
left: tlbr.col,
bottom: tlbr.row,
right: tlbr.col,
sheetName: tlbr.sheetName
};
}
}
break;
case 0:
this.model = {
top: 0,
left: 0,
bottom: 0,
right: 0
};
break;
default:
throw new Error('Invalid number of arguments to _getDimensions() - ' + argv.length);
}
},
get top() {
return this.model.top || 1;
},
set top(value) {
this.model.top = value;
},
get left() {
return this.model.left || 1;
},
set left(value) {
this.model.left = value;
},
get bottom() {
return this.model.bottom || 1;
},
set bottom(value) {
this.model.bottom = value;
},
get right() {
return this.model.right || 1;
},
set right(value) {
this.model.right = value;
},
get sheetName() {
return this.model.sheetName;
},
set sheetName(value) {
this.model.sheetName = value;
},
get _serialisedSheetName() {
var sheetName = this.model.sheetName;
if (sheetName) {
if (/^[a-zA-Z0-9]*$/.test(sheetName)) {
return sheetName + '!';
}
return '\'' + sheetName + '\'!';
}
return '';
},
expand: function expand(top, left, bottom, right) {
if (!this.model.top || top < this.top) this.top = top;
if (!this.model.left || left < this.left) this.left = left;
if (!this.model.bottom || bottom > this.bottom) this.bottom = bottom;
if (!this.model.right || right > this.right) this.right = right;
},
expandRow: function expandRow(row) {
if (row) {
var dimensions = row.dimensions;
if (dimensions) {
this.expand(row.number, dimensions.min, row.number, dimensions.max);
}
}
},
expandToAddress: function expandToAddress(addressStr) {
var address = colCache.decodeEx(addressStr);
this.expand(address.row, address.col, address.row, address.col);
},
get tl() {
return colCache.n2l(this.left) + this.top;
},
get $t$l() {
return '$' + colCache.n2l(this.left) + '$' + this.top;
},
get br() {
return colCache.n2l(this.right) + this.bottom;
},
get $b$r() {
return '$' + colCache.n2l(this.right) + '$' + this.bottom;
},
get range() {
return this._serialisedSheetName + this.tl + ':' + this.br;
},
get $range() {
return this._serialisedSheetName + this.$t$l + ':' + this.$b$r;
},
get shortRange() {
return this.count > 1 ? this.range : this._serialisedSheetName + this.tl;
},
get $shortRange() {
return this.count > 1 ? this.$range : this._serialisedSheetName + this.$t$l;
},
get count() {
return (1 + this.bottom - this.top) * (1 + this.right - this.left);
},
toString: function toString() {
return this.range;
},
intersects: function intersects(other) {
if (other.sheetName && this.sheetName && other.sheetName !== this.sheetName) return false;
if (other.bottom < this.top) return false;
if (other.top > this.bottom) return false;
if (other.right < this.left) return false;
if (other.left > this.right) return false;
return true;
},
contains: function contains(addressStr) {
var address = colCache.decodeEx(addressStr);
return this.containsEx(address);
},
containsEx: function containsEx(address) {
if (address.sheetName && this.sheetName && address.sheetName !== this.sheetName) return false;
return address.row >= this.top && address.row <= this.bottom && address.col >= this.left && address.col <= this.right;
}
};
//# sourceMappingURL=range.js.map

File diff suppressed because one or more lines are too long

381
src/plugins/exceljs/dist/es5/doc/row.js vendored Normal file
View File

@@ -0,0 +1,381 @@
'use strict';
var _ = require('../utils/under-dash');
var Enums = require('./enums');
var colCache = require('./../utils/col-cache');
var Cell = require('./cell');
var Row = module.exports = function (worksheet, number) {
this._worksheet = worksheet;
this._number = number;
this._cells = [];
this.style = {};
this.outlineLevel = 0;
};
Row.prototype = {
// return the row number
get number() {
return this._number;
},
get worksheet() {
return this._worksheet;
},
// Inform Streaming Writer that this row (and all rows before it) are complete
// and ready to write. Has no effect on Worksheet document
commit: function commit() {
this._worksheet._commitRow(this); // eslint-disable-line no-underscore-dangle
},
// helps GC by breaking cyclic references
destroy: function destroy() {
delete this._worksheet;
delete this._cells;
delete this.style;
},
findCell: function findCell(colNumber) {
return this._cells[colNumber - 1];
},
// given {address, row, col}, find or create new cell
getCellEx: function getCellEx(address) {
var cell = this._cells[address.col - 1];
if (!cell) {
var column = this._worksheet.getColumn(address.col);
cell = new Cell(this, column, address.address);
this._cells[address.col - 1] = cell;
}
return cell;
},
// get cell by key, letter or column number
getCell: function getCell(col) {
if (typeof col === 'string') {
// is it a key?
var column = this._worksheet.getColumnKey(col);
if (column) {
col = column.number;
} else {
col = colCache.l2n(col);
}
}
return this._cells[col - 1] || this.getCellEx({
address: colCache.encodeAddress(this._number, col),
row: this._number,
col: col
});
},
// remove cell(s) and shift all higher cells down by count
splice: function splice(start, count) {
var inserts = Array.prototype.slice.call(arguments, 2);
var nKeep = start + count;
var nExpand = inserts.length - count;
var nEnd = this._cells.length;
var i = void 0,
cSrc = void 0,
cDst = void 0;
if (nExpand < 0) {
// remove cells
for (i = start + inserts.length; i <= nEnd; i++) {
cDst = this._cells[i - 1];
cSrc = this._cells[i - nExpand - 1];
if (cSrc) {
cDst = this.getCell(i);
cDst.value = cSrc.value;
cDst.style = cSrc.style;
} else if (cDst) {
cDst.value = null;
cDst.style = {};
}
}
} else if (nExpand > 0) {
// insert new cells
for (i = nEnd; i >= nKeep; i--) {
cSrc = this._cells[i - 1];
if (cSrc) {
cDst = this.getCell(i + nExpand);
cDst.value = cSrc.value;
cDst.style = cSrc.style;
} else {
this._cells[i + nExpand - 1] = undefined;
}
}
}
// now add the new values
for (i = 0; i < inserts.length; i++) {
cDst = this.getCell(start + i);
cDst.value = inserts[i];
cDst.style = {};
}
},
// Iterate over all non-null cells in this row
eachCell: function eachCell(options, iteratee) {
if (!iteratee) {
iteratee = options;
options = null;
}
if (options && options.includeEmpty) {
var n = this._cells.length;
for (var i = 1; i <= n; i++) {
iteratee(this.getCell(i), i);
}
} else {
this._cells.forEach(function (cell, index) {
if (cell && cell.type !== Enums.ValueType.Null) {
iteratee(cell, index + 1);
}
});
}
},
// ===========================================================================
// Page Breaks
addPageBreak: function addPageBreak(lft, rght) {
var ws = this._worksheet;
var left = Math.max(0, lft - 1) || 0;
var right = Math.max(0, rght - 1) || 16838;
var pb = {
id: this._number,
max: right,
man: 1
};
if (left) pb.min = left;
ws.rowBreaks.push(pb);
},
// return a sparse array of cell values
get values() {
var values = [];
this._cells.forEach(function (cell) {
if (cell && cell.type !== Enums.ValueType.Null) {
values[cell.col] = cell.value;
}
});
return values;
},
// set the values by contiguous or sparse array, or by key'd object literal
set values(value) {
var _this = this;
// this operation is not additive - any prior cells are removed
this._cells = [];
if (!value) {
// empty row
} else if (value instanceof Array) {
var offset = 0;
if (value.hasOwnProperty('0')) {
// contiguous array - start at column 1
offset = 1;
}
value.forEach(function (item, index) {
if (item !== undefined) {
_this.getCellEx({
address: colCache.encodeAddress(_this._number, index + offset),
row: _this._number,
col: index + offset
}).value = item;
}
});
} else {
// assume object with column keys
this._worksheet.eachColumnKey(function (column, key) {
if (value[key] !== undefined) {
_this.getCellEx({
address: colCache.encodeAddress(_this._number, column.number),
row: _this._number,
col: column.number
}).value = value[key];
}
});
}
},
// returns true if the row includes at least one cell with a value
get hasValues() {
return _.some(this._cells, function (cell) {
return cell && cell.type !== Enums.ValueType.Null;
});
},
get cellCount() {
return this._cells.length;
},
get actualCellCount() {
var count = 0;
this.eachCell(function () {
count++;
});
return count;
},
// get the min and max column number for the non-null cells in this row or null
get dimensions() {
var min = 0;
var max = 0;
this._cells.forEach(function (cell) {
if (cell && cell.type !== Enums.ValueType.Null) {
if (!min || min > cell.col) {
min = cell.col;
}
if (max < cell.col) {
max = cell.col;
}
}
});
return min > 0 ? {
min: min,
max: max
} : null;
},
// =========================================================================
// styles
_applyStyle: function _applyStyle(name, value) {
this.style[name] = value;
this._cells.forEach(function (cell) {
if (cell) {
cell[name] = value;
}
});
return value;
},
get numFmt() {
return this.style.numFmt;
},
set numFmt(value) {
this._applyStyle('numFmt', value);
},
get font() {
return this.style.font;
},
set font(value) {
this._applyStyle('font', value);
},
get alignment() {
return this.style.alignment;
},
set alignment(value) {
this._applyStyle('alignment', value);
},
get border() {
return this.style.border;
},
set border(value) {
this._applyStyle('border', value);
},
get fill() {
return this.style.fill;
},
set fill(value) {
this._applyStyle('fill', value);
},
get hidden() {
return !!this._hidden;
},
set hidden(value) {
this._hidden = value;
},
get outlineLevel() {
return this._outlineLevel || 0;
},
set outlineLevel(value) {
this._outlineLevel = value;
},
get collapsed() {
return !!(this._outlineLevel && this._outlineLevel >= this._worksheet.properties.outlineLevelRow);
},
// =========================================================================
get model() {
var cells = [];
var min = 0;
var max = 0;
this._cells.forEach(function (cell) {
if (cell) {
var cellModel = cell.model;
if (cellModel) {
if (!min || min > cell.col) {
min = cell.col;
}
if (max < cell.col) {
max = cell.col;
}
cells.push(cellModel);
}
}
});
return this.height || cells.length ? {
cells: cells,
number: this.number,
min: min,
max: max,
height: this.height,
style: this.style,
hidden: this.hidden,
outlineLevel: this.outlineLevel,
collapsed: this.collapsed
} : null;
},
set model(value) {
var _this2 = this;
if (value.number !== this._number) {
throw new Error('Invalid row number in model');
}
this._cells = [];
var previousAddress = void 0;
value.cells.forEach(function (cellModel) {
switch (cellModel.type) {
case Cell.Types.Merge:
// special case - don't add this types
break;
default:
var address = void 0;
if (cellModel.address) {
address = colCache.decodeAddress(cellModel.address);
} else if (previousAddress) {
// This is a <c> element without an r attribute
// Assume that it's the cell for the next column
var row = previousAddress.row;
var col = previousAddress.col + 1;
address = {
row: row,
col: col,
address: colCache.encodeAddress(row, col),
$col$row: '$' + colCache.n2l(col) + '$' + row
};
}
previousAddress = address;
var cell = _this2.getCellEx(address);
cell.model = cellModel;
break;
}
});
if (value.height) {
this.height = value.height;
} else {
delete this.height;
}
this.hidden = value.hidden;
this.outlineLevel = value.outlineLevel || 0;
this.style = value.style && JSON.parse(JSON.stringify(value.style)) || {};
}
};
//# sourceMappingURL=row.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,217 @@
'use strict';
var Worksheet = require('./worksheet');
var DefinedNames = require('./defined-names');
var XLSX = require('./../xlsx/xlsx');
var CSV = require('./../csv/csv');
// Workbook requirements
// Load and Save from file and stream
// Access/Add/Delete individual worksheets
// Manage String table, Hyperlink table, etc.
// Manage scaffolding for contained objects to write to/read from
var Workbook = module.exports = function () {
this.created = new Date();
this.modified = this.created;
this.properties = {};
this._worksheets = [];
this.views = [];
this.media = [];
this._definedNames = new DefinedNames();
};
Workbook.prototype = {
get xlsx() {
if (!this._xlsx) this._xlsx = new XLSX(this);
return this._xlsx;
},
get csv() {
if (!this._csv) this._csv = new CSV(this);
return this._csv;
},
get nextId() {
// find the next unique spot to add worksheet
var i;
for (i = 1; i < this._worksheets.length; i++) {
if (!this._worksheets[i]) {
return i;
}
}
return this._worksheets.length || 1;
},
addWorksheet: function addWorksheet(name, options) {
var id = this.nextId;
name = name || 'sheet' + id;
// if options is a color, call it tabColor (and signal deprecated message)
if (options) {
if (typeof options === 'string') {
// eslint-disable-next-line no-console
console.trace('tabColor argument is now deprecated. Please use workbook.addWorksheet(name, {properties: { tabColor: { argb: "rbg value" } }');
options = {
properties: {
tabColor: { argb: options }
}
};
} else if (options.argb || options.theme || options.indexed) {
// eslint-disable-next-line no-console
console.trace('tabColor argument is now deprecated. Please use workbook.addWorksheet(name, {properties: { tabColor: { ... } }');
options = {
properties: {
tabColor: options
}
};
}
}
var lastOrderNo = this._worksheets.reduce(function (acc, ws) {
return (ws && ws.orderNo) > acc ? ws.orderNo : acc;
}, 0);
var worksheetOptions = Object.assign({}, options, {
id: id,
name: name,
orderNo: lastOrderNo + 1,
workbook: this
});
var worksheet = new Worksheet(worksheetOptions);
this._worksheets[id] = worksheet;
return worksheet;
},
removeWorksheetEx: function removeWorksheetEx(worksheet) {
delete this._worksheets[worksheet.id];
},
removeWorksheet: function removeWorksheet(id) {
var worksheet = this.getWorksheet(id);
if (worksheet) {
worksheet.destroy();
}
},
getWorksheet: function getWorksheet(id) {
if (id === undefined) {
return this._worksheets.find(function (worksheet) {
return worksheet;
});
} else if (typeof id === 'number') {
return this._worksheets[id];
} else if (typeof id === 'string') {
return this._worksheets.find(function (worksheet) {
return worksheet && worksheet.name === id;
});
}
return undefined;
},
get worksheets() {
// return a clone of _worksheets
return this._worksheets.slice(1).sort(function (a, b) {
return a.orderNo - b.orderNo;
}).filter(Boolean);
},
eachSheet: function eachSheet(iteratee) {
this.worksheets.forEach(function (sheet) {
iteratee(sheet, sheet.id);
});
},
get definedNames() {
return this._definedNames;
},
clearThemes: function clearThemes() {
// Note: themes are not an exposed feature, meddle at your peril!
this._themes = undefined;
},
addImage: function addImage(image) {
// TODO: validation?
var id = this.media.length;
this.media.push(Object.assign({}, image, { type: 'image' }));
return id;
},
getImage: function getImage(id) {
return this.media[id];
},
get model() {
return {
creator: this.creator || 'Unknown',
lastModifiedBy: this.lastModifiedBy || 'Unknown',
lastPrinted: this.lastPrinted,
created: this.created,
modified: this.modified,
properties: this.properties,
worksheets: this.worksheets.map(function (worksheet) {
return worksheet.model;
}),
sheets: this.worksheets.map(function (ws) {
return ws.model;
}).filter(Boolean),
definedNames: this._definedNames.model,
views: this.views,
company: this.company,
manager: this.manager,
title: this.title,
subject: this.subject,
keywords: this.keywords,
category: this.category,
description: this.description,
language: this.language,
revision: this.revision,
contentStatus: this.contentStatus,
themes: this._themes,
media: this.media
};
},
set model(value) {
var _this = this;
this.creator = value.creator;
this.lastModifiedBy = value.lastModifiedBy;
this.lastPrinted = value.lastPrinted;
this.created = value.created;
this.modified = value.modified;
this.company = value.company;
this.manager = value.manager;
this.title = value.title;
this.subject = value.subject;
this.keywords = value.keywords;
this.category = value.category;
this.description = value.description;
this.language = value.language;
this.revision = value.revision;
this.contentStatus = value.contentStatus;
this.properties = value.properties;
this._worksheets = [];
value.worksheets.forEach(function (worksheetModel) {
var id = worksheetModel.id;
var name = worksheetModel.name;
var orderNo = value.sheets.findIndex(function (ws) {
return ws.id === id;
});
var state = worksheetModel.state;
var worksheet = _this._worksheets[id] = new Worksheet({
id: id,
name: name,
orderNo: orderNo,
state: state,
workbook: _this
});
worksheet.model = worksheetModel;
});
this._definedNames.model = value.definedNames;
this.views = value.views;
this._themes = value.themes;
this.media = value.media || [];
}
};
//# sourceMappingURL=workbook.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,689 @@
'use strict';
var _ = require('../utils/under-dash');
var colCache = require('./../utils/col-cache');
var Range = require('./range');
var Row = require('./row');
var Column = require('./column');
var Enums = require('./enums');
var Anchor = require('./anchor');
var DataValidations = require('./data-validations');
// Worksheet requirements
// Operate as sheet inside workbook or standalone
// Load and Save from file and stream
// Access/Add/Delete individual cells
// Manage column widths and row heights
var Worksheet = function Worksheet(options) {
options = options || {};
// in a workbook, each sheet will have a number
this.id = options.id;
this.orderNo = options.orderNo;
// and a name
this.name = options.name || 'Sheet' + this.id;
// add a state
this.state = options.state || 'visible';
// rows allows access organised by row. Sparse array of arrays indexed by row-1, col
// Note: _rows is zero based. Must subtract 1 to go from cell.row to index
this._rows = [];
// column definitions
this._columns = null;
// column keys (addRow convenience): key ==> this._collumns index
this._keys = {};
// keep record of all merges
this._merges = {};
// record of all row and column pageBreaks
this.rowBreaks = [];
this._workbook = options.workbook;
// for tabColor, default row height, outline levels, etc
this.properties = Object.assign({}, {
defaultRowHeight: 15,
dyDescent: 55,
outlineLevelCol: 0,
outlineLevelRow: 0
}, options.properties);
// for all things printing
this.pageSetup = Object.assign({}, {
margins: { left: 0.7, right: 0.7, top: 0.75, bottom: 0.75, header: 0.3, footer: 0.3 },
orientation: 'portrait',
horizontalDpi: 4294967295,
verticalDpi: 4294967295,
fitToPage: !!(options.pageSetup && (options.pageSetup.fitToWidth || options.pageSetup.fitToHeight) && !options.pageSetup.scale),
pageOrder: 'downThenOver',
blackAndWhite: false,
draft: false,
cellComments: 'None',
errors: 'displayed',
scale: 100,
fitToWidth: 1,
fitToHeight: 1,
paperSize: undefined,
showRowColHeaders: false,
showGridLines: false,
firstPageNumber: undefined,
horizontalCentered: false,
verticalCentered: false,
rowBreaks: null,
colBreaks: null
}, options.pageSetup);
this.dataValidations = new DataValidations();
// for freezepanes, split, zoom, gridlines, etc
this.views = options.views || [];
this.autoFilter = options.autoFilter || null;
// for images, etc
this._media = [];
};
Worksheet.prototype = {
get workbook() {
return this._workbook;
},
// when you're done with this worksheet, call this to remove from workbook
destroy: function destroy() {
this._workbook.removeWorksheetEx(this);
},
// Get the bounding range of the cells in this worksheet
get dimensions() {
var dimensions = new Range();
this._rows.forEach(function (row) {
if (row) {
var rowDims = row.dimensions;
if (rowDims) {
dimensions.expand(row.number, rowDims.min, row.number, rowDims.max);
}
}
});
return dimensions;
},
// =========================================================================
// Columns
// get the current columns array.
get columns() {
return this._columns;
},
// set the columns from an array of column definitions.
// Note: any headers defined will overwrite existing values.
set columns(value) {
var _this = this;
// calculate max header row count
this._headerRowCount = value.reduce(function (pv, cv) {
var headerCount = cv.header && 1 || cv.headers && cv.headers.length || 0;
return Math.max(pv, headerCount);
}, 0);
// construct Column objects
var count = 1;
var columns = this._columns = [];
value.forEach(function (defn) {
var column = new Column(_this, count++, false);
columns.push(column);
column.defn = defn;
});
},
getColumnKey: function getColumnKey(key) {
return this._keys[key];
},
setColumnKey: function setColumnKey(key, value) {
this._keys[key] = value;
},
deleteColumnKey: function deleteColumnKey(key) {
delete this._keys[key];
},
eachColumnKey: function eachColumnKey(f) {
_.each(this._keys, f);
},
// get a single column by col number. If it doesn't exist, create it and any gaps before it
getColumn: function getColumn(c) {
if (typeof c === 'string') {
// if it matches a key'd column, return that
var col = this._keys[c];
if (col) return col;
// otherwise, assume letter
c = colCache.l2n(c);
}
if (!this._columns) {
this._columns = [];
}
if (c > this._columns.length) {
var n = this._columns.length + 1;
while (n <= c) {
this._columns.push(new Column(this, n++));
}
}
return this._columns[c - 1];
},
spliceColumns: function spliceColumns(start, count) {
var _this2 = this;
// each member of inserts is a column of data.
var i = void 0;
var inserts = Array.prototype.slice.call(arguments, 2);
var rows = this._rows;
var nRows = rows.length;
if (inserts.length > 0) {
var _loop = function _loop() {
var rowArguments = [start, count];
inserts.forEach(function (insert) {
// eslint-disable-line no-loop-func
rowArguments.push(insert[i] || null);
});
var row = _this2.getRow(i + 1);
// eslint-disable-next-line prefer-spread
row.splice.apply(row, rowArguments);
};
// must iterate over all rows whether they exist yet or not
for (i = 0; i < nRows; i++) {
_loop();
}
} else {
// nothing to insert, so just splice all rows
this._rows.forEach(function (r, i) {
if (r) {
r.splice(start, count);
}
});
}
// splice column definitions
var nExpand = inserts.length - count;
var nKeep = start + count;
var nEnd = this._columns.length;
if (nExpand < 0) {
for (i = start + inserts.length; i <= nEnd; i++) {
this.getColumn(i).defn = this.getColumn(i - nExpand).defn;
}
} else if (nExpand > 0) {
for (i = nEnd; i >= nKeep; i--) {
this.getColumn(i + nExpand).defn = this.getColumn(i).defn;
}
}
for (i = start; i < start + inserts.length; i++) {
this.getColumn(i).defn = null;
}
},
get columnCount() {
var maxCount = 0;
this.eachRow(function (row) {
maxCount = Math.max(maxCount, row.cellCount);
});
return maxCount;
},
get actualColumnCount() {
// performance nightmare - for each row, counts all the columns used
var counts = [];
var count = 0;
this.eachRow(function (row) {
row.eachCell(function (cell) {
var col = cell.col;
if (!counts[col]) {
counts[col] = true;
count++;
}
});
});
return count;
},
// =========================================================================
// Rows
_commitRow: function _commitRow() {
// nop - allows streaming reader to fill a document
},
get _lastRowNumber() {
// need to cope with results of splice
var rows = this._rows;
var n = rows.length;
while (n > 0 && rows[n - 1] === undefined) {
n--;
}
return n;
},
get _nextRow() {
return this._lastRowNumber + 1;
},
get lastRow() {
if (this._rows.length) {
return this._rows[this._rows.length - 1];
}
return undefined;
},
// find a row (if exists) by row number
findRow: function findRow(r) {
return this._rows[r - 1];
},
get rowCount() {
return this._lastRowNumber;
},
get actualRowCount() {
// counts actual rows that have actual data
var count = 0;
this.eachRow(function () {
count++;
});
return count;
},
// get a row by row number.
getRow: function getRow(r) {
var row = this._rows[r - 1];
if (!row) {
row = this._rows[r - 1] = new Row(this, r);
}
return row;
},
addRow: function addRow(value) {
var row = this.getRow(this._nextRow);
row.values = value;
return row;
},
addRows: function addRows(value) {
var _this3 = this;
value.forEach(function (row) {
_this3.addRow(row);
});
},
spliceRows: function spliceRows(start, count) {
var _this4 = this;
// same problem as row.splice, except worse.
var inserts = Array.prototype.slice.call(arguments, 2);
var nKeep = start + count;
var nExpand = inserts.length - count;
var nEnd = this._rows.length;
var i = void 0,
rSrc = void 0;
if (nExpand < 0) {
// remove rows
for (i = nKeep; i <= nEnd; i++) {
rSrc = this._rows[i - 1];
if (rSrc) {
(function () {
var rDst = _this4.getRow(i + nExpand);
rDst.values = rSrc.values;
rDst.style = rSrc.style;
// eslint-disable-next-line no-loop-func
rSrc.eachCell({ includeEmpty: true }, function (cell, colNumber) {
rDst.getCell(colNumber).style = cell.style;
});
_this4._rows[i - 1] = undefined;
})();
} else {
this._rows[i + nExpand - 1] = undefined;
}
}
} else if (nExpand > 0) {
// insert new cells
for (i = nEnd; i >= nKeep; i--) {
rSrc = this._rows[i - 1];
if (rSrc) {
(function () {
var rDst = _this4.getRow(i + nExpand);
rDst.values = rSrc.values;
rDst.style = rSrc.style;
// eslint-disable-next-line no-loop-func
rSrc.eachCell({ includeEmpty: true }, function (cell, colNumber) {
rDst.getCell(colNumber).style = cell.style;
});
})();
} else {
this._rows[i + nExpand - 1] = undefined;
}
}
}
// now copy over the new values
for (i = 0; i < inserts.length; i++) {
var rDst = this.getRow(start + i);
rDst.style = {};
rDst.values = inserts[i];
}
},
// iterate over every row in the worksheet, including maybe empty rows
eachRow: function eachRow(options, iteratee) {
if (!iteratee) {
iteratee = options;
options = undefined;
}
if (options && options.includeEmpty) {
var n = this._rows.length;
for (var i = 1; i <= n; i++) {
iteratee(this.getRow(i), i);
}
} else {
this._rows.forEach(function (row) {
if (row && row.hasValues) {
iteratee(row, row.number);
}
});
}
},
// return all rows as sparse array
getSheetValues: function getSheetValues() {
var rows = [];
this._rows.forEach(function (row) {
if (row) {
rows[row.number] = row.values;
}
});
return rows;
},
// =========================================================================
// Cells
// returns the cell at [r,c] or address given by r. If not found, return undefined
findCell: function findCell(r, c) {
var address = colCache.getAddress(r, c);
var row = this._rows[address.row - 1];
return row ? row.findCell(address.col) : undefined;
},
// return the cell at [r,c] or address given by r. If not found, create a new one.
getCell: function getCell(r, c) {
var address = colCache.getAddress(r, c);
var row = this.getRow(address.row);
return row.getCellEx(address);
},
// =========================================================================
// Merge
// convert the range defined by ['tl:br'], [tl,br] or [t,l,b,r] into a single 'merged' cell
mergeCells: function mergeCells() {
var dimensions = new Range(Array.prototype.slice.call(arguments, 0)); // convert arguments into Array
// check cells aren't already merged
_.each(this._merges, function (merge) {
if (merge.intersects(dimensions)) {
throw new Error('Cannot merge already merged cells');
}
});
// apply merge
var master = this.getCell(dimensions.top, dimensions.left);
for (var i = dimensions.top; i <= dimensions.bottom; i++) {
for (var j = dimensions.left; j <= dimensions.right; j++) {
// merge all but the master cell
if (i > dimensions.top || j > dimensions.left) {
this.getCell(i, j).merge(master);
}
}
}
// index merge
this._merges[master.address] = dimensions;
},
_unMergeMaster: function _unMergeMaster(master) {
// master is always top left of a rectangle
var merge = this._merges[master.address];
if (merge) {
for (var i = merge.top; i <= merge.bottom; i++) {
for (var j = merge.left; j <= merge.right; j++) {
this.getCell(i, j).unmerge();
}
}
delete this._merges[master.address];
}
},
get hasMerges() {
return _.some(this._merges, function () {
// TODO: this doesn't look right
return true;
});
},
// scan the range defined by ['tl:br'], [tl,br] or [t,l,b,r] and if any cell is part of a merge,
// un-merge the group. Note this function can affect multiple merges and merge-blocks are
// atomic - either they're all merged or all un-merged.
unMergeCells: function unMergeCells() {
var dimensions = new Range(Array.prototype.slice.call(arguments, 0)); // convert arguments into Array
// find any cells in that range and unmerge them
for (var i = dimensions.top; i <= dimensions.bottom; i++) {
for (var j = dimensions.left; j <= dimensions.right; j++) {
var cell = this.findCell(i, j);
if (cell) {
if (cell.type === Enums.ValueType.Merge) {
// this cell merges to another master
this._unMergeMaster(cell.master);
} else if (this._merges[cell.address]) {
// this cell is a master
this._unMergeMaster(cell);
}
}
}
}
},
// ===========================================================================
// Shared Formula
fillFormula: function fillFormula(range, formula, results) {
// Define formula for top-left cell and share to rest
var decoded = colCache.decode(range);
var top = decoded.top,
left = decoded.left,
bottom = decoded.bottom,
right = decoded.right;
var width = right - left + 1;
var masterAddress = colCache.encodeAddress(top, left);
// work out result accessor
var getResult = void 0;
if (typeof results === 'function') {
getResult = results;
} else if (Array.isArray(results)) {
if (Array.isArray(results[0])) {
getResult = function getResult(row, col) {
return results[row - top][col - left];
};
} else {
getResult = function getResult(row, col) {
return results[(row - top) * width + (col - left)];
};
}
} else {
getResult = function getResult() {
return undefined;
};
}
var first = true;
for (var r = top; r <= bottom; r++) {
for (var c = left; c <= right; c++) {
if (first) {
this.getCell(r, c).value = {
formula: formula,
result: getResult(r, c)
};
first = false;
} else {
this.getCell(r, c).value = {
sharedFormula: masterAddress,
result: getResult(r, c)
};
}
}
}
},
// =========================================================================
// Images
addImage: function addImageToCells(imageId, range) {
if (range.tl && !(range.tl instanceof Anchor)) {
range.tl = new Anchor(range.tl);
range.tl.worksheet = this;
}
if (range.br && !(range.br instanceof Anchor)) {
range.br = new Anchor(range.br);
range.br.worksheet = this;
}
this._media.push({
type: 'image',
imageId: imageId,
range: range
});
},
getImages: function getImages() {
return this._media.filter(function (m) {
return m.type === 'image';
});
},
addBackgroundImage: function addBackgroundImage(imageId) {
this._media.push({
type: 'background',
imageId: imageId
});
},
getBackgroundImageId: function getBackgroundImageId() {
return this._media.filter(function (m) {
return m.type === 'background';
}).map(function (m) {
return m.imageId;
})[0];
},
// ===========================================================================
// Deprecated
get tabColor() {
// eslint-disable-next-line no-console
console.trace('worksheet.tabColor property is now deprecated. Please use worksheet.properties.tabColor');
return this.properties.tabColor;
},
set tabColor(value) {
// eslint-disable-next-line no-console
console.trace('worksheet.tabColor property is now deprecated. Please use worksheet.properties.tabColor');
this.properties.tabColor = value;
},
// ===========================================================================
// Model
get model() {
var model = {
id: this.id,
name: this.name,
dataValidations: this.dataValidations.model,
properties: this.properties,
state: this.state,
pageSetup: this.pageSetup,
rowBreaks: this.rowBreaks,
views: this.views,
autoFilter: this.autoFilter,
media: this._media
};
// =================================================
// columns
model.cols = Column.toModel(this.columns);
// ==========================================================
// Rows
var rows = model.rows = [];
var dimensions = model.dimensions = new Range();
this._rows.forEach(function (row) {
var rowModel = row && row.model;
if (rowModel) {
dimensions.expand(rowModel.number, rowModel.min, rowModel.number, rowModel.max);
rows.push(rowModel);
}
});
// ==========================================================
// Merges
model.merges = [];
_.each(this._merges, function (merge) {
model.merges.push(merge.range);
});
return model;
},
_parseRows: function _parseRows(model) {
var _this5 = this;
this._rows = [];
model.rows.forEach(function (rowModel) {
var row = new Row(_this5, rowModel.number);
_this5._rows[row.number - 1] = row;
row.model = rowModel;
});
},
_parseMergeCells: function _parseMergeCells(model) {
var _this6 = this;
_.each(model.mergeCells, function (merge) {
_this6.mergeCells(merge);
});
},
set model(value) {
var _this7 = this;
this.name = value.name;
this._columns = Column.fromModel(this, value.cols);
this._parseRows(value);
this._parseMergeCells(value);
this.dataValidations = new DataValidations(value.dataValidations);
this.properties = value.properties;
this.pageSetup = value.pageSetup;
this.views = value.views;
this.autoFilter = value.autoFilter;
this._media = value.media;
this._media.filter(function (m) {
return m.type === 'image' && typeof m.range !== 'string';
}).forEach(function (i) {
i.range.tl.worksheet = _this7;
i.range.br.worksheet = _this7;
});
}
};
module.exports = Worksheet;
//# sourceMappingURL=worksheet.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,19 @@
'use strict';
// for the benefit of browserify, include browser friendly promise
var setConfigValue = require('./config/set-value');
setConfigValue('promise', require('promish/dist/promish-node'), false);
var ExcelJS = {
Workbook: require('./doc/workbook')
};
// Object.assign mono-fill
var Enums = require('./doc/enums');
Object.keys(Enums).forEach(function (key) {
ExcelJS[key] = Enums[key];
});
module.exports = ExcelJS;
//# sourceMappingURL=exceljs.browser.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../lib/exceljs.browser.js"],"names":["setConfigValue","require","ExcelJS","Workbook","Enums","Object","keys","forEach","key","module","exports"],"mappings":";;AAAA;AACA,IAAIA,iBAAiBC,QAAQ,oBAAR,CAArB;AACAD,eAAe,SAAf,EAA0BC,QAAQ,2BAAR,CAA1B,EAAgE,KAAhE;;AAEA,IAAIC,UAAU;AACZC,YAAUF,QAAQ,gBAAR;AADE,CAAd;;AAIA;AACA,IAAIG,QAAQH,QAAQ,aAAR,CAAZ;;AAEAI,OAAOC,IAAP,CAAYF,KAAZ,EAAmBG,OAAnB,CAA2B,eAAO;AAChCL,UAAQM,GAAR,IAAeJ,MAAMI,GAAN,CAAf;AACD,CAFD;;AAIAC,OAAOC,OAAP,GAAiBR,OAAjB","file":"exceljs.browser.js","sourcesContent":["// for the benefit of browserify, include browser friendly promise\nvar setConfigValue = require('./config/set-value');\nsetConfigValue('promise', require('promish/dist/promish-node'), false);\n\nvar ExcelJS = {\n Workbook: require('./doc/workbook')\n};\n\n// Object.assign mono-fill\nvar Enums = require('./doc/enums');\n\nObject.keys(Enums).forEach(key => {\n ExcelJS[key] = Enums[key];\n});\n\nmodule.exports = ExcelJS;\n"]}

View File

@@ -0,0 +1,23 @@
'use strict';
var setConfigValue = require('./config/set-value');
setConfigValue('promise', require('promish'), false);
var ExcelJS = {
Workbook: require('./doc/workbook'),
ModelContainer: require('./doc/modelcontainer'),
stream: {
xlsx: {
WorkbookWriter: require('./stream/xlsx/workbook-writer'),
WorkbookReader: require('./stream/xlsx/workbook-reader')
}
},
config: {
setValue: require('./config/set-value')
}
};
Object.assign(ExcelJS, require('./doc/enums'));
module.exports = ExcelJS;
//# sourceMappingURL=exceljs.nodejs.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../lib/exceljs.nodejs.js"],"names":["setConfigValue","require","ExcelJS","Workbook","ModelContainer","stream","xlsx","WorkbookWriter","WorkbookReader","config","setValue","Object","assign","module","exports"],"mappings":";;AAAA,IAAIA,iBAAiBC,QAAQ,oBAAR,CAArB;AACAD,eAAe,SAAf,EAA0BC,QAAQ,SAAR,CAA1B,EAA8C,KAA9C;;AAEA,IAAIC,UAAU;AACZC,YAAUF,QAAQ,gBAAR,CADE;AAEZG,kBAAgBH,QAAQ,sBAAR,CAFJ;AAGZI,UAAQ;AACNC,UAAM;AACJC,sBAAgBN,QAAQ,+BAAR,CADZ;AAEJO,sBAAgBP,QAAQ,+BAAR;AAFZ;AADA,GAHI;AASZQ,UAAQ;AACNC,cAAUT,QAAQ,oBAAR;AADJ;AATI,CAAd;;AAcAU,OAAOC,MAAP,CAAcV,OAAd,EAAuBD,QAAQ,aAAR,CAAvB;;AAEAY,OAAOC,OAAP,GAAiBZ,OAAjB","file":"exceljs.nodejs.js","sourcesContent":["var setConfigValue = require('./config/set-value');\nsetConfigValue('promise', require('promish'), false);\n\nvar ExcelJS = {\n Workbook: require('./doc/workbook'),\n ModelContainer: require('./doc/modelcontainer'),\n stream: {\n xlsx: {\n WorkbookWriter: require('./stream/xlsx/workbook-writer'),\n WorkbookReader: require('./stream/xlsx/workbook-reader')\n }\n },\n config: {\n setValue: require('./config/set-value')\n }\n};\n\nObject.assign(ExcelJS, require('./doc/enums'));\n\nmodule.exports = ExcelJS;\n"]}

23
src/plugins/exceljs/dist/es5/index.js vendored Normal file
View File

@@ -0,0 +1,23 @@
'use strict';
var setConfigValue = require('./config/set-value');
setConfigValue('promise', require('promish'), false);
var ExcelJS = {
Workbook: require('./doc/workbook'),
ModelContainer: require('./doc/modelcontainer'),
stream: {
xlsx: {
WorkbookWriter: require('./stream/xlsx/workbook-writer'),
WorkbookReader: require('./stream/xlsx/workbook-reader')
}
},
config: {
setValue: require('./config/set-value')
}
};
Object.assign(ExcelJS, require('./doc/enums'));
module.exports = ExcelJS;
//# sourceMappingURL=exceljs.nodejs.js.map

View File

@@ -0,0 +1,80 @@
'use strict';
var events = require('events');
var Sax = require('sax');
var utils = require('../../utils/utils');
var Enums = require('../../doc/enums');
var RelType = require('../../xlsx/rel-type');
var HyperlinkReader = module.exports = function (workbook, id) {
// in a workbook, each sheet will have a number
this.id = id;
this._workbook = workbook;
};
utils.inherits(HyperlinkReader, events.EventEmitter, {
get count() {
return this.hyperlinks && this.hyperlinks.length || 0;
},
each: function each(fn) {
return this.hyperlinks.forEach(fn);
},
read: function read(entry, options) {
var self = this;
var emitHyperlinks = false;
var hyperlinks = null;
switch (options.hyperlinks) {
case 'emit':
emitHyperlinks = true;
break;
case 'cache':
this.hyperlinks = hyperlinks = {};
break;
default:
break;
}
if (!emitHyperlinks && !hyperlinks) {
entry.autodrain();
self.emit('finished');
return;
}
var parser = Sax.createStream(true, {});
parser.on('opentag', function (node) {
if (node.name === 'Relationship') {
var rId = node.attributes.Id;
switch (node.attributes.Type) {
case RelType.Hyperlink:
var relationship = {
type: Enums.RelationshipType.Styles,
rId: rId,
target: node.attributes.Target,
targetMode: node.attributes.TargetMode
};
if (emitHyperlinks) {
self.emit('hyperlink', relationship);
} else {
hyperlinks[relationship.rId] = relationship;
}
break;
default:
break;
}
}
});
parser.on('end', function () {
self.emit('finished');
});
// create a down-stream flow-control to regulate the stream
var flowControl = this._workbook.flowControl.createChild();
flowControl.pipe(parser, { sync: true });
entry.pipe(flowControl);
}
});
//# sourceMappingURL=hyperlink-reader.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../lib/stream/xlsx/hyperlink-reader.js"],"names":["events","require","Sax","utils","Enums","RelType","HyperlinkReader","module","exports","workbook","id","_workbook","inherits","EventEmitter","count","hyperlinks","length","each","fn","forEach","read","entry","options","self","emitHyperlinks","autodrain","emit","parser","createStream","on","node","name","rId","attributes","Id","Type","Hyperlink","relationship","type","RelationshipType","Styles","target","Target","targetMode","TargetMode","flowControl","createChild","pipe","sync"],"mappings":"AAAA;;AAEA,IAAIA,SAASC,QAAQ,QAAR,CAAb;AACA,IAAIC,MAAMD,QAAQ,KAAR,CAAV;;AAEA,IAAIE,QAAQF,QAAQ,mBAAR,CAAZ;AACA,IAAIG,QAAQH,QAAQ,iBAAR,CAAZ;AACA,IAAII,UAAUJ,QAAQ,qBAAR,CAAd;;AAEA,IAAIK,kBAAkBC,OAAOC,OAAP,GAAiB,UAASC,QAAT,EAAmBC,EAAnB,EAAuB;AAC5D;AACA,OAAKA,EAAL,GAAUA,EAAV;;AAEA,OAAKC,SAAL,GAAiBF,QAAjB;AACD,CALD;;AAOAN,MAAMS,QAAN,CAAeN,eAAf,EAAgCN,OAAOa,YAAvC,EAAqD;;AAEnD,MAAIC,KAAJ,GAAY;AACV,WAAQ,KAAKC,UAAL,IAAmB,KAAKA,UAAL,CAAgBC,MAApC,IAA+C,CAAtD;AACD,GAJkD;;AAMnDC,QAAM,cAASC,EAAT,EAAa;AACjB,WAAO,KAAKH,UAAL,CAAgBI,OAAhB,CAAwBD,EAAxB,CAAP;AACD,GARkD;;AAUnDE,QAAM,cAASC,KAAT,EAAgBC,OAAhB,EAAyB;AAC7B,QAAIC,OAAO,IAAX;AACA,QAAIC,iBAAiB,KAArB;AACA,QAAIT,aAAa,IAAjB;AACA,YAAQO,QAAQP,UAAhB;AACE,WAAK,MAAL;AACES,yBAAiB,IAAjB;AACA;AACF,WAAK,OAAL;AACE,aAAKT,UAAL,GAAkBA,aAAa,EAA/B;AACA;AACF;AACE;AARJ;AAUA,QAAI,CAACS,cAAD,IAAmB,CAACT,UAAxB,EAAoC;AAClCM,YAAMI,SAAN;AACAF,WAAKG,IAAL,CAAU,UAAV;AACA;AACD;;AAED,QAAIC,SAASzB,IAAI0B,YAAJ,CAAiB,IAAjB,EAAuB,EAAvB,CAAb;AACAD,WAAOE,EAAP,CAAU,SAAV,EAAqB,UAASC,IAAT,EAAe;AAClC,UAAIA,KAAKC,IAAL,KAAc,cAAlB,EAAkC;AAChC,YAAIC,MAAMF,KAAKG,UAAL,CAAgBC,EAA1B;AACA,gBAAQJ,KAAKG,UAAL,CAAgBE,IAAxB;AACE,eAAK9B,QAAQ+B,SAAb;AACE,gBAAIC,eAAe;AACjBC,oBAAMlC,MAAMmC,gBAAN,CAAuBC,MADZ;AAEjBR,mBAAKA,GAFY;AAGjBS,sBAAQX,KAAKG,UAAL,CAAgBS,MAHP;AAIjBC,0BAAYb,KAAKG,UAAL,CAAgBW;AAJX,aAAnB;AAMA,gBAAIpB,cAAJ,EAAoB;AAClBD,mBAAKG,IAAL,CAAU,WAAV,EAAuBW,YAAvB;AACD,aAFD,MAEO;AACLtB,yBAAWsB,aAAaL,GAAxB,IAA+BK,YAA/B;AACD;AACD;AACF;AACE;AAfJ;AAiBD;AACF,KArBD;AAsBAV,WAAOE,EAAP,CAAU,KAAV,EAAiB,YAAW;AAC1BN,WAAKG,IAAL,CAAU,UAAV;AACD,KAFD;;AAIA;AACA,QAAImB,cAAc,KAAKlC,SAAL,CAAekC,WAAf,CAA2BC,WAA3B,EAAlB;AACAD,gBAAYE,IAAZ,CAAiBpB,MAAjB,EAAyB,EAACqB,MAAM,IAAP,EAAzB;AACA3B,UAAM0B,IAAN,CAAWF,WAAX;AACD;AA7DkD,CAArD","file":"hyperlink-reader.js","sourcesContent":["'use strict';\n\nvar events = require('events');\nvar Sax = require('sax');\n\nvar utils = require('../../utils/utils');\nvar Enums = require('../../doc/enums');\nvar RelType = require('../../xlsx/rel-type');\n\nvar HyperlinkReader = module.exports = function(workbook, id) {\n // in a workbook, each sheet will have a number\n this.id = id;\n\n this._workbook = workbook;\n};\n\nutils.inherits(HyperlinkReader, events.EventEmitter, {\n\n get count() {\n return (this.hyperlinks && this.hyperlinks.length) || 0;\n },\n\n each: function(fn) {\n return this.hyperlinks.forEach(fn);\n },\n\n read: function(entry, options) {\n var self = this;\n var emitHyperlinks = false;\n var hyperlinks = null;\n switch (options.hyperlinks) {\n case 'emit':\n emitHyperlinks = true;\n break;\n case 'cache':\n this.hyperlinks = hyperlinks = {};\n break;\n default:\n break;\n }\n if (!emitHyperlinks && !hyperlinks) {\n entry.autodrain();\n self.emit('finished');\n return;\n }\n\n var parser = Sax.createStream(true, {});\n parser.on('opentag', function(node) {\n if (node.name === 'Relationship') {\n var rId = node.attributes.Id;\n switch (node.attributes.Type) {\n case RelType.Hyperlink:\n var relationship = {\n type: Enums.RelationshipType.Styles,\n rId: rId,\n target: node.attributes.Target,\n targetMode: node.attributes.TargetMode\n };\n if (emitHyperlinks) {\n self.emit('hyperlink', relationship);\n } else {\n hyperlinks[relationship.rId] = relationship;\n }\n break;\n default:\n break;\n }\n }\n });\n parser.on('end', function() {\n self.emit('finished');\n });\n\n // create a down-stream flow-control to regulate the stream\n var flowControl = this._workbook.flowControl.createChild();\n flowControl.pipe(parser, {sync: true});\n entry.pipe(flowControl);\n }\n});\n"]}

View File

@@ -0,0 +1,100 @@
'use strict';
var utils = require('../../utils/utils');
var RelType = require('../../xlsx/rel-type');
var HyperlinksProxy = function HyperlinksProxy(sheetRelsWriter) {
this.writer = sheetRelsWriter;
};
HyperlinksProxy.prototype = {
push: function push(hyperlink) {
this.writer.addHyperlink(hyperlink);
}
};
var SheetRelsWriter = module.exports = function (options) {
// in a workbook, each sheet will have a number
this.id = options.id;
// count of all relationships
this.count = 0;
// keep record of all hyperlinks
this._hyperlinks = [];
this._workbook = options.workbook;
};
SheetRelsWriter.prototype = {
get stream() {
if (!this._stream) {
// eslint-disable-next-line no-underscore-dangle
this._stream = this._workbook._openStream('/xl/worksheets/_rels/sheet' + this.id + '.xml.rels');
}
return this._stream;
},
get length() {
return this._hyperlinks.length;
},
each: function each(fn) {
return this._hyperlinks.forEach(fn);
},
get hyperlinksProxy() {
return this._hyperlinksProxy || (this._hyperlinksProxy = new HyperlinksProxy(this));
},
addHyperlink: function addHyperlink(hyperlink) {
// Write to stream
var relationship = {
Target: hyperlink.target,
Type: RelType.Hyperlink,
TargetMode: 'External'
};
var rId = this._writeRelationship(relationship);
// store sheet stuff for later
this._hyperlinks.push({
rId: rId,
address: hyperlink.address
});
},
addMedia: function addMedia(media) {
return this._writeRelationship(media);
},
commit: function commit() {
if (this.count) {
// write xml utro
this._writeClose();
// and close stream
this.stream.end();
}
},
// ================================================================================
_writeOpen: function _writeOpen() {
this.stream.write('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' + '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">');
},
_writeRelationship: function _writeRelationship(relationship) {
if (!this.count) {
this._writeOpen();
}
var rId = 'rId' + ++this.count;
if (relationship.TargetMode) {
this.stream.write('<Relationship' + ' Id="' + rId + '"' + ' Type="' + relationship.Type + '"' + ' Target="' + utils.xmlEncode(relationship.Target) + '"' + ' TargetMode="' + relationship.TargetMode + '"' + '/>');
} else {
this.stream.write('<Relationship' + ' Id="' + rId + '"' + ' Type="' + relationship.Type + '"' + ' Target="' + relationship.Target + '"' + '/>');
}
return rId;
},
_writeClose: function _writeClose() {
this.stream.write('</Relationships>');
}
};
//# sourceMappingURL=sheet-rels-writer.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,272 @@
'use strict';
var fs = require('fs');
var events = require('events');
var Stream = require('stream');
var unzip = require('unzipper');
var Sax = require('sax');
var tmp = require('tmp');
var utils = require('../../utils/utils');
var FlowControl = require('../../utils/flow-control');
var StyleManager = require('../../xlsx/xform/style/styles-xform');
var WorkbookPropertiesManager = require('../../xlsx/xform/book/workbook-properties-xform');
var WorksheetReader = require('./worksheet-reader');
var HyperlinkReader = require('./hyperlink-reader');
tmp.setGracefulCleanup();
var WorkbookReader = module.exports = function (options) {
this.options = options = options || {};
this.styles = new StyleManager();
this.styles.init();
this.properties = new WorkbookPropertiesManager();
// worksheet readers, indexed by sheetNo
this.worksheetReaders = {};
// hyperlink readers, indexed by sheetNo
this.hyperlinkReaders = {};
// count the open readers
this.readers = 0;
// end of stream check
this.atEnd = false;
// worksheets, deferred for parsing after shared strings reading
this.waitingWorkSheets = [];
// callbacks for temp files cleanup
this.tempFileCleanupCallbacks = [];
};
utils.inherits(WorkbookReader, events.EventEmitter, {
_getStream: function _getStream(input) {
if (input instanceof Stream.Readable) {
return input;
}
if (typeof input === 'string') {
return fs.createReadStream(input);
}
throw new Error('Could not recognise input');
},
get flowControl() {
if (!this._flowControl) {
this._flowControl = new FlowControl(this.options);
}
return this._flowControl;
},
options: {
entries: ['emit'],
sharedStrings: ['cache', 'emit'],
styles: ['cache'],
hyperlinks: ['cache', 'emit'],
worksheets: ['emit']
},
read: function read(input, options) {
var _this = this;
var stream = this.stream = this._getStream(input);
var zip = this.zip = unzip.Parse();
zip.on('entry', function (entry) {
var match, sheetNo;
// console.log(entry.path);
switch (entry.path) {
case '_rels/.rels':
case 'xl/_rels/workbook.xml.rels':
entry.autodrain();
break;
case 'xl/workbook.xml':
_this._parseWorkbook(entry, options);
break;
case 'xl/sharedStrings.xml':
_this._parseSharedStrings(entry, options);
break;
case 'xl/styles.xml':
_this._parseStyles(entry, options);
break;
default:
if (entry.path.match(/xl\/worksheets\/sheet\d+[.]xml/)) {
match = entry.path.match(/xl\/worksheets\/sheet(\d+)[.]xml/);
sheetNo = match[1];
if (_this.sharedStrings) {
_this._parseWorksheet(entry, sheetNo, options);
} else {
// create temp file for each worksheet
tmp.file(function (err, path, fd, cleanupCallback) {
if (err) throw err;
var tempStream = fs.createWriteStream(path);
_this.waitingWorkSheets.push({ sheetNo: sheetNo, options: options, path: path });
entry.pipe(tempStream);
_this.tempFileCleanupCallbacks.push(cleanupCallback);
});
}
} else if (entry.path.match(/xl\/worksheets\/_rels\/sheet\d+[.]xml.rels/)) {
match = entry.path.match(/xl\/worksheets\/_rels\/sheet(\d+)[.]xml.rels/);
sheetNo = match[1];
_this._parseHyperlinks(entry, sheetNo, options);
} else {
entry.autodrain();
}
break;
}
});
zip.on('close', function () {
if (_this.waitingWorkSheets.length) {
var currentBook = 0;
var processBooks = function processBooks() {
var worksheetInfo = _this.waitingWorkSheets[currentBook];
var entry = fs.createReadStream(worksheetInfo.path);
var sheetNo = worksheetInfo.sheetNo;
var options = worksheetInfo.options;
var worksheet = _this._parseWorksheet(entry, sheetNo, options);
worksheet.on('finished', function (node) {
++currentBook;
if (currentBook === _this.waitingWorkSheets.length) {
// temp files cleaning up
_this.tempFileCleanupCallbacks.forEach(function (cb) {
cb();
});
_this.tempFileCleanupCallbacks = [];
_this.emit('end');
_this.atEnd = true;
if (!_this.readers) {
_this.emit('finished');
}
} else {
setImmediate(processBooks);
}
});
};
setImmediate(processBooks);
} else {
_this.emit('end');
_this.atEnd = true;
if (!_this.readers) {
_this.emit('finished');
}
}
});
zip.on('error', function (err) {
_this.emit('error', err);
});
// Pipe stream into top flow-control
// this.flowControl.pipe(zip);
stream.pipe(zip);
},
_emitEntry: function _emitEntry(options, payload) {
if (options.entries === 'emit') {
this.emit('entry', payload);
}
},
_parseWorkbook: function _parseWorkbook(entry, options) {
this._emitEntry(options, { type: 'workbook' });
this.properties.parseStream(entry);
},
_parseSharedStrings: function _parseSharedStrings(entry, options) {
this._emitEntry(options, { type: 'shared-strings' });
var self = this;
var sharedStrings = null;
switch (options.sharedStrings) {
case 'cache':
sharedStrings = this.sharedStrings = [];
break;
case 'emit':
break;
default:
entry.autodrain();
return;
}
var parser = Sax.createStream(true, {});
var inT = false;
var t = null;
var index = 0;
parser.on('opentag', function (node) {
if (node.name === 't') {
t = null;
inT = true;
}
});
parser.on('closetag', function (name) {
if (inT && name === 't') {
if (sharedStrings) {
sharedStrings.push(t);
} else {
self.emit('shared-string', { index: index++, text: t });
}
t = null;
}
});
parser.on('text', function (text) {
t = t ? t + text : text;
});
parser.on('error', function (error) {
self.emit('error', error);
});
entry.pipe(parser);
},
_parseStyles: function _parseStyles(entry, options) {
this._emitEntry(options, { type: 'styles' });
if (options.styles !== 'cache') {
entry.autodrain();
return;
}
this.styles = new StyleManager();
this.styles.parseStream(entry);
},
_getReader: function _getReader(Type, collection, sheetNo) {
var self = this;
var reader = collection[sheetNo];
if (!reader) {
reader = new Type(this, sheetNo);
self.readers++;
reader.on('finished', function () {
if (! --self.readers) {
if (self.atEnd) {
self.emit('finished');
}
}
});
collection[sheetNo] = reader;
}
return reader;
},
_parseWorksheet: function _parseWorksheet(entry, sheetNo, options) {
this._emitEntry(options, { type: 'worksheet', id: sheetNo });
var worksheetReader = this._getReader(WorksheetReader, this.worksheetReaders, sheetNo);
if (options.worksheets === 'emit') {
this.emit('worksheet', worksheetReader);
}
worksheetReader.read(entry, options, this.hyperlinkReaders[sheetNo]);
return worksheetReader;
},
_parseHyperlinks: function _parseHyperlinks(entry, sheetNo, options) {
this._emitEntry(options, { type: 'hyerlinks', id: sheetNo });
var hyperlinksReader = this._getReader(HyperlinkReader, this.hyperlinkReaders, sheetNo);
if (options.hyperlinks === 'emit') {
this.emit('hyperlinks', hyperlinksReader);
}
hyperlinksReader.read(entry, options);
}
});
//# sourceMappingURL=workbook-reader.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,290 @@
'use strict';
var fs = require('fs');
var Archiver = require('archiver');
var PromishLib = require('../../utils/promish');
var StreamBuf = require('../../utils/stream-buf');
var RelType = require('../../xlsx/rel-type');
var StylesXform = require('../../xlsx/xform/style/styles-xform');
var SharedStrings = require('../../utils/shared-strings');
var DefinedNames = require('../../doc/defined-names');
var CoreXform = require('../../xlsx/xform/core/core-xform');
var RelationshipsXform = require('../../xlsx/xform/core/relationships-xform');
var ContentTypesXform = require('../../xlsx/xform/core/content-types-xform');
var AppXform = require('../../xlsx/xform/core/app-xform');
var WorkbookXform = require('../../xlsx/xform/book/workbook-xform');
var SharedStringsXform = require('../../xlsx/xform/strings/shared-strings-xform');
var WorksheetWriter = require('./worksheet-writer');
var theme1Xml = require('../../xlsx/xml/theme1.js');
var WorkbookWriter = module.exports = function (options) {
options = options || {};
this.created = options.created || new Date();
this.modified = options.modified || this.created;
this.creator = options.creator || 'ExcelJS';
this.lastModifiedBy = options.lastModifiedBy || 'ExcelJS';
this.lastPrinted = options.lastPrinted;
// using shared strings creates a smaller xlsx file but may use more memory
this.useSharedStrings = options.useSharedStrings || false;
this.sharedStrings = new SharedStrings();
// style manager
this.styles = options.useStyles ? new StylesXform(true) : new StylesXform.Mock(true);
// defined names
this._definedNames = new DefinedNames();
this._worksheets = [];
this.views = [];
this.media = [];
this.zip = Archiver('zip');
if (options.stream) {
this.stream = options.stream;
} else if (options.filename) {
this.stream = fs.createWriteStream(options.filename);
} else {
this.stream = new StreamBuf();
}
this.zip.pipe(this.stream);
// these bits can be added right now
this.promise = PromishLib.Promish.all([this.addThemes(), this.addOfficeRels()]);
};
WorkbookWriter.prototype = {
get definedNames() {
return this._definedNames;
},
_openStream: function _openStream(path) {
var self = this;
var stream = new StreamBuf({ bufSize: 65536, batch: true });
self.zip.append(stream, { name: path });
stream.on('finish', function () {
stream.emit('zipped');
});
return stream;
},
_commitWorksheets: function _commitWorksheets() {
var commitWorksheet = function commitWorksheet(worksheet) {
if (!worksheet.committed) {
return new PromishLib.Promish(function (resolve) {
worksheet.stream.on('zipped', function () {
resolve();
});
worksheet.commit();
});
}
return PromishLib.Promish.resolve();
};
// if there are any uncommitted worksheets, commit them now and wait
var promises = this._worksheets.map(commitWorksheet);
if (promises.length) {
return PromishLib.Promish.all(promises);
}
return PromishLib.Promish.resolve();
},
commit: function commit() {
var _this = this;
// commit all worksheets, then add suplimentary files
return this.promise.then(function () {
return _this._commitWorksheets();
}).then(function () {
return PromishLib.Promish.all([_this.addContentTypes(), _this.addApp(), _this.addCore(), _this.addSharedStrings(), _this.addStyles(), _this.addWorkbookRels()]);
}).then(function () {
return _this.addWorkbook();
}).then(function () {
return _this._finalize();
});
},
get nextId() {
// find the next unique spot to add worksheet
var i;
for (i = 1; i < this._worksheets.length; i++) {
if (!this._worksheets[i]) {
return i;
}
}
return this._worksheets.length || 1;
},
addWorksheet: function addWorksheet(name, options) {
// it's possible to add a worksheet with different than default
// shared string handling
// in fact, it's even possible to switch it mid-sheet
options = options || {};
var useSharedStrings = options.useSharedStrings !== undefined ? options.useSharedStrings : this.useSharedStrings;
if (options.tabColor) {
// eslint-disable-next-line no-console
console.trace('tabColor option has moved to { properties: tabColor: {...} }');
options.properties = Object.assign({
tabColor: options.tabColor
}, options.properties);
}
var id = this.nextId;
name = name || 'sheet' + id;
var worksheet = new WorksheetWriter({
id: id,
name: name,
workbook: this,
useSharedStrings: useSharedStrings,
properties: options.properties,
state: options.state,
pageSetup: options.pageSetup,
views: options.views,
autoFilter: options.autoFilter
});
this._worksheets[id] = worksheet;
return worksheet;
},
getWorksheet: function getWorksheet(id) {
if (id === undefined) {
return this._worksheets.find(function () {
return true;
});
} else if (typeof id === 'number') {
return this._worksheets[id];
} else if (typeof id === 'string') {
return this._worksheets.find(function (worksheet) {
return worksheet && worksheet.name === id;
});
}
return undefined;
},
addStyles: function addStyles() {
var self = this;
return new PromishLib.Promish(function (resolve) {
self.zip.append(self.styles.xml, { name: 'xl/styles.xml' });
resolve();
});
},
addThemes: function addThemes() {
var self = this;
return new PromishLib.Promish(function (resolve) {
self.zip.append(theme1Xml, { name: 'xl/theme/theme1.xml' });
resolve();
});
},
addOfficeRels: function addOfficeRels() {
var self = this;
return new PromishLib.Promish(function (resolve) {
var xform = new RelationshipsXform();
var xml = xform.toXml([{ Id: 'rId1', Type: RelType.OfficeDocument, Target: 'xl/workbook.xml' }, { Id: 'rId2', Type: RelType.CoreProperties, Target: 'docProps/core.xml' }, { Id: 'rId3', Type: RelType.ExtenderProperties, Target: 'docProps/app.xml' }]);
self.zip.append(xml, { name: '/_rels/.rels' });
resolve();
});
},
addContentTypes: function addContentTypes() {
var _this2 = this;
return new PromishLib.Promish(function (resolve) {
var model = {
worksheets: _this2._worksheets.filter(Boolean),
sharedStrings: _this2.sharedStrings
};
var xform = new ContentTypesXform();
var xml = xform.toXml(model);
_this2.zip.append(xml, { name: '[Content_Types].xml' });
resolve();
});
},
addApp: function addApp() {
var _this3 = this;
return new PromishLib.Promish(function (resolve) {
var model = {
worksheets: _this3._worksheets.filter(Boolean)
};
var xform = new AppXform();
var xml = xform.toXml(model);
_this3.zip.append(xml, { name: 'docProps/app.xml' });
resolve();
});
},
addCore: function addCore() {
var self = this;
return new PromishLib.Promish(function (resolve) {
var coreXform = new CoreXform();
var xml = coreXform.toXml(self);
self.zip.append(xml, { name: 'docProps/core.xml' });
resolve();
});
},
addSharedStrings: function addSharedStrings() {
var self = this;
if (this.sharedStrings.count) {
return new PromishLib.Promish(function (resolve) {
var sharedStringsXform = new SharedStringsXform();
var xml = sharedStringsXform.toXml(self.sharedStrings);
self.zip.append(xml, { name: '/xl/sharedStrings.xml' });
resolve();
});
}
return PromishLib.Promish.resolve();
},
addWorkbookRels: function addWorkbookRels() {
var self = this;
var count = 1;
var relationships = [{ Id: 'rId' + count++, Type: RelType.Styles, Target: 'styles.xml' }, { Id: 'rId' + count++, Type: RelType.Theme, Target: 'theme/theme1.xml' }];
if (this.sharedStrings.count) {
relationships.push({ Id: 'rId' + count++, Type: RelType.SharedStrings, Target: 'sharedStrings.xml' });
}
this._worksheets.forEach(function (worksheet) {
if (worksheet) {
worksheet.rId = 'rId' + count++;
relationships.push({ Id: worksheet.rId, Type: RelType.Worksheet, Target: 'worksheets/sheet' + worksheet.id + '.xml' });
}
});
return new PromishLib.Promish(function (resolve) {
var xform = new RelationshipsXform();
var xml = xform.toXml(relationships);
self.zip.append(xml, { name: '/xl/_rels/workbook.xml.rels' });
resolve();
});
},
addWorkbook: function addWorkbook() {
var zip = this.zip;
var model = {
worksheets: this._worksheets.filter(Boolean),
definedNames: this._definedNames.model,
views: this.views,
properties: {}
};
return new PromishLib.Promish(function (resolve) {
var xform = new WorkbookXform();
xform.prepare(model);
zip.append(xform.toXml(model), { name: '/xl/workbook.xml' });
resolve();
});
},
_finalize: function _finalize() {
var _this4 = this;
return new PromishLib.Promish(function (resolve, reject) {
_this4.stream.on('error', reject);
_this4.stream.on('finish', function () {
resolve(_this4);
});
_this4.zip.on('error', reject);
_this4.zip.finalize();
});
}
};
//# sourceMappingURL=workbook-writer.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,351 @@
'use strict';
var events = require('events');
var Sax = require('sax');
var _ = require('../../utils/under-dash');
var utils = require('../../utils/utils');
var colCache = require('../../utils/col-cache');
var Dimensions = require('../../doc/range');
var Row = require('../../doc/row');
var Column = require('../../doc/column');
var WorksheetReader = module.exports = function (workbook, id) {
this.workbook = workbook;
this.id = id;
// and a name
this.name = 'Sheet' + this.id;
// column definitions
this._columns = null;
this._keys = {};
// keep a record of dimensions
this._dimensions = new Dimensions();
};
utils.inherits(WorksheetReader, events.EventEmitter, {
// destroy - not a valid operation for a streaming writer
// even though some streamers might be able to, it's a bad idea.
destroy: function destroy() {
throw new Error('Invalid Operation: destroy');
},
// return the current dimensions of the writer
get dimensions() {
return this._dimensions;
},
// =========================================================================
// Columns
// get the current columns array.
get columns() {
return this._columns;
},
// get a single column by col number. If it doesn't exist, it and any gaps before it
// are created.
getColumn: function getColumn(c) {
if (typeof c === 'string') {
// if it matches a key'd column, return that
var col = this._keys[c];
if (col) {
return col;
}
// otherise, assume letter
c = colCache.l2n(c);
}
if (!this._columns) {
this._columns = [];
}
if (c > this._columns.length) {
var n = this._columns.length + 1;
while (n <= c) {
this._columns.push(new Column(this, n++));
}
}
return this._columns[c - 1];
},
getColumnKey: function getColumnKey(key) {
return this._keys[key];
},
setColumnKey: function setColumnKey(key, value) {
this._keys[key] = value;
},
deleteColumnKey: function deleteColumnKey(key) {
delete this._keys[key];
},
eachColumnKey: function eachColumnKey(f) {
_.each(this._keys, f);
},
// =========================================================================
// Read
_emitRow: function _emitRow(row) {
this.emit('row', row);
},
read: function read(entry, options) {
var _this = this;
var emitSheet = false;
var emitHyperlinks = false;
var hyperlinks = null;
switch (options.worksheets) {
case 'emit':
emitSheet = true;
break;
case 'prep':
break;
default:
break;
}
switch (options.hyperlinks) {
case 'emit':
emitHyperlinks = true;
break;
case 'cache':
this.hyperlinks = hyperlinks = {};
break;
default:
break;
}
if (!emitSheet && !emitHyperlinks && !hyperlinks) {
entry.autodrain();
this.emit('finished');
return;
}
// references
var sharedStrings = this.workbook.sharedStrings;
var styles = this.workbook.styles;
var properties = this.workbook.properties;
// xml position
var inCols = false;
var inRows = false;
var inHyperlinks = false;
// parse state
var cols = null;
var row = null;
var c = null;
var current = null;
var parser = Sax.createStream(true, {});
parser.on('opentag', function (node) {
if (emitSheet) {
switch (node.name) {
case 'cols':
inCols = true;
cols = [];
break;
case 'sheetData':
inRows = true;
break;
case 'col':
if (inCols) {
cols.push({
min: parseInt(node.attributes.min, 10),
max: parseInt(node.attributes.max, 10),
width: parseFloat(node.attributes.width),
styleId: parseInt(node.attributes.style || '0', 10)
});
}
break;
case 'row':
if (inRows) {
var r = parseInt(node.attributes.r, 10);
row = new Row(_this, r);
if (node.attributes.ht) {
row.height = parseFloat(node.attributes.ht);
}
if (node.attributes.s) {
var styleId = parseInt(node.attributes.s, 10);
var style = styles.getStyleModel(styleId);
if (style) {
row.style = style;
}
}
}
break;
case 'c':
if (row) {
c = {
ref: node.attributes.r,
s: parseInt(node.attributes.s, 10),
t: node.attributes.t
};
}
break;
case 'f':
if (c) {
current = c.f = { text: '' };
}
break;
case 'v':
if (c) {
current = c.v = { text: '' };
}
break;
case 'mergeCell':
break;
default:
break;
}
}
// =================================================================
//
if (emitHyperlinks || hyperlinks) {
switch (node.name) {
case 'hyperlinks':
inHyperlinks = true;
break;
case 'hyperlink':
if (inHyperlinks) {
var hyperlink = {
ref: node.attributes.ref,
rId: node.attributes['r:id']
};
if (emitHyperlinks) {
_this.emit('hyperlink', hyperlink);
} else {
hyperlinks[hyperlink.ref] = hyperlink;
}
}
break;
default:
break;
}
}
});
// only text data is for sheet values
parser.on('text', function (text) {
if (emitSheet) {
if (current) {
current.text += text;
}
}
});
parser.on('closetag', function (name) {
if (emitSheet) {
switch (name) {
case 'cols':
inCols = false;
_this._columns = Column.fromModel(cols);
break;
case 'sheetData':
inRows = false;
break;
case 'row':
_this._dimensions.expandRow(row);
_this._emitRow(row);
row = null;
break;
case 'c':
if (row && c) {
var address = colCache.decodeAddress(c.ref);
var cell = row.getCell(address.col);
if (c.s) {
var style = styles.getStyleModel(c.s);
if (style) {
cell.style = style;
}
}
if (c.f) {
var value = {
formula: c.f.text
};
if (c.v) {
if (c.t === 'str') {
value.result = utils.xmlDecode(c.v.text);
} else {
value.result = parseFloat(c.v.text);
}
}
cell.value = value;
} else if (c.v) {
switch (c.t) {
case 's':
var index = parseInt(c.v.text, 10);
if (sharedStrings) {
cell.value = sharedStrings[index];
} else {
cell.value = {
sharedString: index
};
}
break;
case 'str':
cell.value = utils.xmlDecode(c.v.text);
break;
case 'e':
cell.value = { error: c.v.text };
break;
case 'b':
cell.value = parseInt(c.v.text, 10) !== 0;
break;
default:
if (utils.isDateFmt(cell.numFmt)) {
cell.value = utils.excelToDate(parseFloat(c.v.text), properties.model.date1904);
} else {
cell.value = parseFloat(c.v.text);
}
break;
}
}
if (hyperlinks) {
var hyperlink = hyperlinks[c.ref];
if (hyperlink) {
cell.text = cell.value;
cell.value = undefined;
cell.hyperlink = hyperlink;
}
}
c = null;
}
break;
default:
break;
}
}
if (emitHyperlinks || hyperlinks) {
switch (name) {
case 'hyperlinks':
inHyperlinks = false;
break;
default:
break;
}
}
});
parser.on('error', function (error) {
_this.emit('error', error);
});
parser.on('end', function () {
_this.emit('finished');
});
// create a down-stream flow-control to regulate the stream
var flowControl = this.workbook.flowControl.createChild();
flowControl.pipe(parser, { sync: true });
entry.pipe(flowControl);
}
});
//# sourceMappingURL=worksheet-reader.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,530 @@
'use strict';
var _ = require('../../utils/under-dash');
var RelType = require('../../xlsx/rel-type');
var colCache = require('../../utils/col-cache');
var Dimensions = require('../../doc/range');
var StringBuf = require('../../utils/string-buf');
var Row = require('../../doc/row');
var Column = require('../../doc/column');
var SheetRelsWriter = require('./sheet-rels-writer');
var DataValidations = require('../../doc/data-validations');
var xmlBuffer = new StringBuf();
// ============================================================================================
// Xforms
var ListXform = require('../../xlsx/xform/list-xform');
var DataValidationsXform = require('../../xlsx/xform/sheet/data-validations-xform');
var SheetPropertiesXform = require('../../xlsx/xform/sheet/sheet-properties-xform');
var SheetFormatPropertiesXform = require('../../xlsx/xform/sheet/sheet-format-properties-xform');
var ColXform = require('../../xlsx/xform/sheet/col-xform');
var RowXform = require('../../xlsx/xform/sheet/row-xform');
var HyperlinkXform = require('../../xlsx/xform/sheet/hyperlink-xform');
var SheetViewXform = require('../../xlsx/xform/sheet/sheet-view-xform');
var PageMarginsXform = require('../../xlsx/xform/sheet/page-margins-xform');
var PageSetupXform = require('../../xlsx/xform/sheet/page-setup-xform');
var AutoFilterXform = require('../../xlsx/xform/sheet/auto-filter-xform');
var PictureXform = require('../../xlsx/xform/sheet/picture-xform');
// since prepare and render is functional, we can use singletons
var xform = {
dataValidations: new DataValidationsXform(),
sheetProperties: new SheetPropertiesXform(),
sheetFormatProperties: new SheetFormatPropertiesXform(),
columns: new ListXform({ tag: 'cols', length: false, childXform: new ColXform() }),
row: new RowXform(),
hyperlinks: new ListXform({ tag: 'hyperlinks', length: false, childXform: new HyperlinkXform() }),
sheetViews: new ListXform({ tag: 'sheetViews', length: false, childXform: new SheetViewXform() }),
pageMargins: new PageMarginsXform(),
pageSeteup: new PageSetupXform(),
autoFilter: new AutoFilterXform(),
picture: new PictureXform()
};
// ============================================================================================
var WorksheetWriter = module.exports = function (options) {
// in a workbook, each sheet will have a number
this.id = options.id;
// and a name
this.name = options.name || 'Sheet' + this.id;
// add a state
this.state = options.state || 'visible';
// rows are stored here while they need to be worked on.
// when they are committed, they will be deleted.
this._rows = [];
// column definitions
this._columns = null;
// column keys (addRow convenience): key ==> this._columns index
this._keys = {};
// keep record of all merges
this._merges = [];
this._merges.add = function () {}; // ignore cell instruction
// keep record of all hyperlinks
this._sheetRelsWriter = new SheetRelsWriter(options);
// keep a record of dimensions
this._dimensions = new Dimensions();
// first uncommitted row
this._rowZero = 1;
// committed flag
this.committed = false;
// for data validations
this.dataValidations = new DataValidations();
// for sharing formulae
this._formulae = {};
this._siFormulae = 0;
// for default row height, outline levels, etc
this.properties = Object.assign({}, {
defaultRowHeight: 15,
dyDescent: 55,
outlineLevelCol: 0,
outlineLevelRow: 0
}, options.properties);
// for all things printing
this.pageSetup = Object.assign({}, {
margins: { left: 0.7, right: 0.7, top: 0.75, bottom: 0.75, header: 0.3, footer: 0.3 },
orientation: 'portrait',
horizontalDpi: 4294967295,
verticalDpi: 4294967295,
fitToPage: !!(options.pageSetup && (options.pageSetup.fitToWidth || options.pageSetup.fitToHeight) && !options.pageSetup.scale),
pageOrder: 'downThenOver',
blackAndWhite: false,
draft: false,
cellComments: 'None',
errors: 'displayed',
scale: 100,
fitToWidth: 1,
fitToHeight: 1,
paperSize: undefined,
showRowColHeaders: false,
showGridLines: false,
horizontalCentered: false,
verticalCentered: false,
rowBreaks: null,
colBreaks: null
}, options.pageSetup);
// using shared strings creates a smaller xlsx file but may use more memory
this.useSharedStrings = options.useSharedStrings || false;
this._workbook = options.workbook;
// views
this._views = options.views || [];
// auto filter
this.autoFilter = options.autoFilter || null;
// start writing to stream now
this._writeOpenWorksheet();
// background
if (options.background && options.background.type === 'image') {
var imageName = this._workbook.addMedia(options.background);
var pictureId = this._sheetRelsWriter.addMedia({
Target: '../media/' + imageName,
Type: RelType.Image
});
this._background = {
rId: pictureId
};
}
this.startedData = false;
};
WorksheetWriter.prototype = {
get workbook() {
return this._workbook;
},
get stream() {
if (!this._stream) {
// eslint-disable-next-line no-underscore-dangle
this._stream = this._workbook._openStream('/xl/worksheets/sheet' + this.id + '.xml');
// pause stream to prevent 'data' events
this._stream.pause();
}
return this._stream;
},
// destroy - not a valid operation for a streaming writer
// even though some streamers might be able to, it's a bad idea.
destroy: function destroy() {
throw new Error('Invalid Operation: destroy');
},
commit: function commit() {
var _this = this;
if (this.committed) {
return;
}
// commit all rows
this._rows.forEach(function (cRow) {
if (cRow) {
// write the row to the stream
_this._writeRow(cRow);
}
});
// we _cannot_ accept new rows from now on
this._rows = null;
if (!this.startedData) {
this._writeOpenSheetData();
}
this._writeCloseSheetData();
this._writeAutoFilter();
this._writeMergeCells();
// for some reason, Excel can't handle dimensions at the bottom of the file
// this._writeDimensions();
this._writeHyperlinks();
this._writeDataValidations();
this._writePageMargins();
this._writePageSetup();
this._writeBackground();
this._writeCloseWorksheet();
// signal end of stream to workbook
this.stream.end();
// also commit the hyperlinks if any
this._sheetRelsWriter.commit();
this.committed = true;
},
// return the current dimensions of the writer
get dimensions() {
return this._dimensions;
},
get views() {
return this._views;
},
// =========================================================================
// Columns
// get the current columns array.
get columns() {
return this._columns;
},
// set the columns from an array of column definitions.
// Note: any headers defined will overwrite existing values.
set columns(value) {
var _this2 = this;
// calculate max header row count
this._headerRowCount = value.reduce(function (pv, cv) {
var headerCount = cv.header && 1 || cv.headers && cv.headers.length || 0;
return Math.max(pv, headerCount);
}, 0);
// construct Column objects
var count = 1;
var columns = this._columns = [];
value.forEach(function (defn) {
var column = new Column(_this2, count++, false);
columns.push(column);
column.defn = defn;
});
},
getColumnKey: function getColumnKey(key) {
return this._keys[key];
},
setColumnKey: function setColumnKey(key, value) {
this._keys[key] = value;
},
deleteColumnKey: function deleteColumnKey(key) {
delete this._keys[key];
},
eachColumnKey: function eachColumnKey(f) {
_.each(this._keys, f);
},
// get a single column by col number. If it doesn't exist, it and any gaps before it
// are created.
getColumn: function getColumn(c) {
if (typeof c === 'string') {
// if it matches a key'd column, return that
var col = this._keys[c];
if (col) return col;
// otherwise, assume letter
c = colCache.l2n(c);
}
if (!this._columns) {
this._columns = [];
}
if (c > this._columns.length) {
var n = this._columns.length + 1;
while (n <= c) {
this._columns.push(new Column(this, n++));
}
}
return this._columns[c - 1];
},
// =========================================================================
// Rows
get _nextRow() {
return this._rowZero + this._rows.length;
},
// iterate over every uncommitted row in the worksheet, including maybe empty rows
eachRow: function eachRow(options, iteratee) {
if (!iteratee) {
iteratee = options;
options = undefined;
}
if (options && options.includeEmpty) {
var n = this._nextRow;
for (var i = this._rowZero; i < n; i++) {
iteratee(this.getRow(i), i);
}
} else {
this._rows.forEach(function (row) {
if (row.hasValues) {
iteratee(row, row.number);
}
});
}
},
_commitRow: function _commitRow(cRow) {
// since rows must be written in order, we commit all rows up till and including cRow
var found = false;
while (this._rows.length && !found) {
var row = this._rows.shift();
this._rowZero++;
if (row) {
this._writeRow(row);
found = row.number === cRow.number;
this._rowZero = row.number + 1;
}
}
},
get lastRow() {
// returns last uncommitted row
if (this._rows.length) {
return this._rows[this._rows.length - 1];
}
return undefined;
},
// find a row (if exists) by row number
findRow: function findRow(rowNumber) {
var index = rowNumber - this._rowZero;
return this._rows[index];
},
getRow: function getRow(rowNumber) {
var index = rowNumber - this._rowZero;
// may fail if rows have been comitted
if (index < 0) {
throw new Error('Out of bounds: this row has been committed');
}
var row = this._rows[index];
if (!row) {
this._rows[index] = row = new Row(this, rowNumber);
}
return row;
},
addRow: function addRow(value) {
var row = new Row(this, this._nextRow);
this._rows[row.number - this._rowZero] = row;
row.values = value;
return row;
},
// ================================================================================
// Cells
// returns the cell at [r,c] or address given by r. If not found, return undefined
findCell: function findCell(r, c) {
var address = colCache.getAddress(r, c);
var row = this.findRow(address.row);
return row ? row.findCell(address.column) : undefined;
},
// return the cell at [r,c] or address given by r. If not found, create a new one.
getCell: function getCell(r, c) {
var address = colCache.getAddress(r, c);
var row = this.getRow(address.row);
return row.getCellEx(address);
},
mergeCells: function mergeCells() {
// may fail if rows have been comitted
var dimensions = new Dimensions(Array.prototype.slice.call(arguments, 0)); // convert arguments into Array
// check cells aren't already merged
this._merges.forEach(function (merge) {
if (merge.intersects(dimensions)) {
throw new Error('Cannot merge already merged cells');
}
});
// apply merge
var master = this.getCell(dimensions.top, dimensions.left);
for (var i = dimensions.top; i <= dimensions.bottom; i++) {
for (var j = dimensions.left; j <= dimensions.right; j++) {
if (i > dimensions.top || j > dimensions.left) {
this.getCell(i, j).merge(master);
}
}
}
// index merge
this._merges.push(dimensions);
},
// ================================================================================
_write: function _write(text) {
xmlBuffer.reset();
xmlBuffer.addText(text);
this.stream.write(xmlBuffer);
},
_writeSheetProperties: function _writeSheetProperties(xmlBuf, properties, pageSetup) {
var sheetPropertiesModel = {
outlineProperties: properties && properties.outlineProperties,
tabColor: properties && properties.tabColor,
pageSetup: pageSetup && pageSetup.fitToPage ? {
fitToPage: pageSetup.fitToPage
} : undefined
};
xmlBuf.addText(xform.sheetProperties.toXml(sheetPropertiesModel));
},
_writeSheetFormatProperties: function _writeSheetFormatProperties(xmlBuf, properties) {
var sheetFormatPropertiesModel = properties ? {
defaultRowHeight: properties.defaultRowHeight,
dyDescent: properties.dyDescent,
outlineLevelCol: properties.outlineLevelCol,
outlineLevelRow: properties.outlineLevelRow
} : undefined;
xmlBuf.addText(xform.sheetFormatProperties.toXml(sheetFormatPropertiesModel));
},
_writeOpenWorksheet: function _writeOpenWorksheet() {
xmlBuffer.reset();
xmlBuffer.addText('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
xmlBuffer.addText('<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"' + ' xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"' + ' xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"' + ' mc:Ignorable="x14ac"' + ' xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">');
this._writeSheetProperties(xmlBuffer, this.properties, this.pageSetup);
xmlBuffer.addText(xform.sheetViews.toXml(this.views));
this._writeSheetFormatProperties(xmlBuffer, this.properties);
this.stream.write(xmlBuffer);
},
_writeColumns: function _writeColumns() {
var cols = Column.toModel(this.columns);
if (cols) {
xform.columns.prepare(cols, { styles: this._workbook.styles });
this.stream.write(xform.columns.toXml(cols));
}
},
_writeOpenSheetData: function _writeOpenSheetData() {
this._write('<sheetData>');
},
_writeRow: function _writeRow(row) {
if (!this.startedData) {
this._writeColumns();
this._writeOpenSheetData();
this.startedData = true;
}
if (row.hasValues || row.height) {
var model = row.model;
var options = {
styles: this._workbook.styles,
sharedStrings: this.useSharedStrings ? this._workbook.sharedStrings : undefined,
hyperlinks: this._sheetRelsWriter.hyperlinksProxy,
merges: this._merges,
formulae: this._formulae,
siFormulae: this._siFormulae
};
xform.row.prepare(model, options);
this.stream.write(xform.row.toXml(model));
}
},
_writeCloseSheetData: function _writeCloseSheetData() {
this._write('</sheetData>');
},
_writeMergeCells: function _writeMergeCells() {
if (this._merges.length) {
xmlBuffer.reset();
xmlBuffer.addText('<mergeCells count="' + this._merges.length + '">');
this._merges.forEach(function (merge) {
xmlBuffer.addText('<mergeCell ref="' + merge + '"/>');
});
xmlBuffer.addText('</mergeCells>');
this.stream.write(xmlBuffer);
}
},
_writeHyperlinks: function _writeHyperlinks() {
// eslint-disable-next-line no-underscore-dangle
this.stream.write(xform.hyperlinks.toXml(this._sheetRelsWriter._hyperlinks));
},
_writeDataValidations: function _writeDataValidations() {
this.stream.write(xform.dataValidations.toXml(this.dataValidations.model));
},
_writePageMargins: function _writePageMargins() {
this.stream.write(xform.pageMargins.toXml(this.pageSetup.margins));
},
_writePageSetup: function _writePageSetup() {
this.stream.write(xform.pageSeteup.toXml(this.pageSetup));
},
_writeAutoFilter: function _writeAutoFilter() {
this.stream.write(xform.autoFilter.toXml(this.autoFilter));
},
_writeBackground: function _writeBackground() {
if (this._background) {
this.stream.write(xform.picture.toXml(this._background));
}
},
_writeDimensions: function _writeDimensions() {
// for some reason, Excel can't handle dimensions at the bottom of the file
// and we don't know the dimensions until the commit, so don't write them.
// this._write('<dimension ref="' + this._dimensions + '"/>');
},
_writeCloseWorksheet: function _writeCloseWorksheet() {
this._write('</worksheet>');
}
};
//# sourceMappingURL=worksheet-writer.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,19 @@
'use strict';
var events = require('events');
var utils = require('./utils');
// =============================================================================
// AutoDrain - kind of /dev/null
var AutoDrain = module.exports = function () {};
utils.inherits(AutoDrain, events.EventEmitter, {
write: function write(chunk) {
this.emit('data', chunk);
},
end: function end() {
this.emit('end');
}
});
//# sourceMappingURL=auto-drain.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../lib/utils/auto-drain.js"],"names":["events","require","utils","AutoDrain","module","exports","inherits","EventEmitter","write","chunk","emit","end"],"mappings":"AAAA;;AAEA,IAAIA,SAASC,QAAQ,QAAR,CAAb;;AAEA,IAAIC,QAAQD,QAAQ,SAAR,CAAZ;;AAEA;AACA;AACA,IAAIE,YAAYC,OAAOC,OAAP,GAAiB,YAAW,CAC3C,CADD;;AAGAH,MAAMI,QAAN,CAAeH,SAAf,EAA0BH,OAAOO,YAAjC,EAA+C;AAC7CC,SAAO,eAASC,KAAT,EAAgB;AACrB,SAAKC,IAAL,CAAU,MAAV,EAAkBD,KAAlB;AACD,GAH4C;AAI7CE,OAAK,eAAW;AACd,SAAKD,IAAL,CAAU,KAAV;AACD;AAN4C,CAA/C","file":"auto-drain.js","sourcesContent":["'use strict';\n\nvar events = require('events');\n\nvar utils = require('./utils');\n\n// =============================================================================\n// AutoDrain - kind of /dev/null\nvar AutoDrain = module.exports = function() {\n};\n\nutils.inherits(AutoDrain, events.EventEmitter, {\n write: function(chunk) {\n this.emit('data', chunk);\n },\n end: function() {\n this.emit('end');\n }\n});\n"]}

View File

@@ -0,0 +1,125 @@
'use strict';
var _ = require('./under-dash');
var colCache = require('./col-cache');
var CellMatrix = function CellMatrix(template) {
this.template = template;
this.sheets = {};
};
CellMatrix.prototype = {
addCell: function addCell(addressStr) {
this.addCellEx(colCache.decodeEx(addressStr));
},
getCell: function getCell(addressStr) {
return this.findCellEx(colCache.decodeEx(addressStr), true);
},
findCell: function findCell(addressStr) {
return this.findCellEx(colCache.decodeEx(addressStr), false);
},
findCellAt: function findCellAt(sheetName, rowNumber, colNumber) {
var sheet = this.sheets[sheetName];
var row = sheet && sheet[rowNumber];
return row && row[colNumber];
},
addCellEx: function addCellEx(address) {
if (address.top) {
for (var row = address.top; row <= address.bottom; row++) {
for (var col = address.left; col <= address.right; col++) {
this.getCellAt(address.sheetName, row, col);
}
}
} else {
this.findCellEx(address, true);
}
},
getCellEx: function getCellEx(address) {
return this.findCellEx(address, true);
},
findCellEx: function findCellEx(address, create) {
var sheet = this.findSheet(address, create);
var row = this.findSheetRow(sheet, address, create);
return this.findRowCell(row, address, create);
},
getCellAt: function getCellAt(sheetName, rowNumber, colNumber) {
var sheet = this.sheets[sheetName] || (this.sheets[sheetName] = []);
var row = sheet[rowNumber] || (sheet[rowNumber] = []);
return row[colNumber] || (row[colNumber] = {
sheetName: sheetName,
address: colCache.n2l(colNumber) + rowNumber,
row: rowNumber,
col: colNumber
});
},
removeCellEx: function removeCellEx(address) {
var sheet = this.findSheet(address);
if (!sheet) {
return;
}
var row = this.findSheetRow(sheet, address);
if (!row) {
return;
}
delete row[address.col];
},
forEach: function forEach(callback) {
_.each(this.sheets, function (sheet) {
if (sheet) {
sheet.forEach(function (row) {
if (row) {
row.forEach(function (cell) {
if (cell) {
callback(cell);
}
});
}
});
}
});
},
map: function map(callback) {
var results = [];
this.forEach(function (cell) {
results.push(callback(cell));
});
return results;
},
findSheet: function findSheet(address, create) {
var name = address.sheetName;
if (this.sheets[name]) {
return this.sheets[name];
}
if (create) {
return this.sheets[name] = [];
}
return undefined;
},
findSheetRow: function findSheetRow(sheet, address, create) {
var row = address.row;
if (sheet && sheet[row]) {
return sheet[row];
}
if (create) {
return sheet[row] = [];
}
return undefined;
},
findRowCell: function findRowCell(row, address, create) {
var col = address.col;
if (row && row[col]) {
return row[col];
}
if (create) {
return row[col] = this.template ? Object.assign(address, JSON.parse(JSON.stringify(this.template))) : address;
}
return undefined;
}
};
module.exports = CellMatrix;
//# sourceMappingURL=cell-matrix.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,209 @@
'use strict';
// =========================================================================
// Column Letter to Number conversion
var colCache = module.exports = {
_dictionary: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],
_l2n: {},
_n2l: [],
_level: function _level(n) {
if (n <= 26) {
return 1;
}
if (n <= 26 * 26) {
return 2;
}
return 3;
},
_fill: function _fill(level) {
var c, v, l1, l2, l3;
var n = 1;
if (level >= 1) {
while (n <= 26) {
c = this._dictionary[n - 1];
this._n2l[n] = c;
this._l2n[c] = n;
n++;
}
}
if (level >= 2) {
while (n <= 26 + 26 * 26) {
v = n - (26 + 1);
l1 = v % 26;
l2 = Math.floor(v / 26);
c = this._dictionary[l2] + this._dictionary[l1];
this._n2l[n] = c;
this._l2n[c] = n;
n++;
}
}
if (level >= 3) {
while (n <= 16384) {
v = n - (26 * 26 + 26 + 1);
l1 = v % 26;
l2 = Math.floor(v / 26) % 26;
l3 = Math.floor(v / (26 * 26));
c = this._dictionary[l3] + this._dictionary[l2] + this._dictionary[l1];
this._n2l[n] = c;
this._l2n[c] = n;
n++;
}
}
},
l2n: function l2n(l) {
if (!this._l2n[l]) {
this._fill(l.length);
}
if (!this._l2n[l]) {
throw new Error('Out of bounds. Invalid column letter: ' + l);
}
return this._l2n[l];
},
n2l: function n2l(n) {
if (n < 1 || n > 16384) {
throw new Error('' + n + ' is out of bounds. Excel supports columns from 1 to 16384');
}
if (!this._n2l[n]) {
this._fill(this._level(n));
}
return this._n2l[n];
},
// =========================================================================
// Address processing
_hash: {},
// check if value looks like an address
validateAddress: function validateAddress(value) {
if (!value.match(/^[A-Z]+\d+$/)) {
throw new Error('Invalid Address: ' + value);
}
return true;
},
// convert address string into structure
decodeAddress: function decodeAddress(value) {
var addr = this._hash[value];
if (addr) {
return addr;
}
var matchCol = value.match(/[A-Z]+/);
var col;
var colNumber;
if (matchCol) {
col = matchCol[0];
colNumber = this.l2n(col);
}
var matchRow = value.match(/\d+/);
var row;
var rowNumber;
if (matchRow) {
row = matchRow[0];
rowNumber = parseInt(row, 10);
}
// in case $row$col
value = (col || '') + (row || '');
var address = {
address: value,
col: colNumber,
row: rowNumber,
$col$row: '$' + (col || '') + '$' + (row || '')
};
// mem fix - cache only the tl 100x100 square
if (colNumber <= 100 && rowNumber <= 100) {
this._hash[value] = address;
this._hash[address.$col$row] = address;
}
return address;
},
// convert r,c into structure (if only 1 arg, assume r is address string)
getAddress: function getAddress(r, c) {
if (c) {
var address = this.n2l(c) + r;
return this.decodeAddress(address);
}
return this.decodeAddress(r);
},
// convert [address], [tl:br] into address structures
decode: function decode(value) {
var parts = value.split(':');
if (parts.length === 2) {
var tl = this.decodeAddress(parts[0]);
var br = this.decodeAddress(parts[1]);
var result = {
top: Math.min(tl.row, br.row),
left: Math.min(tl.col, br.col),
bottom: Math.max(tl.row, br.row),
right: Math.max(tl.col, br.col)
};
// reconstruct tl, br and dimensions
result.tl = this.n2l(result.left) + result.top;
result.br = this.n2l(result.right) + result.bottom;
result.dimensions = result.tl + ':' + result.br;
return result;
}
return this.decodeAddress(value);
},
// convert [sheetName!][$]col[$]row[[$]col[$]row] into address or range structures
decodeEx: function decodeEx(value) {
var groups = value.match(/(?:(?:(?:'((?:[^']|'')*)')|([^'^ !]*))!)?(.*)/);
var sheetName = groups[1] || groups[2]; // Qouted and unqouted groups
var reference = groups[3]; // Remaining address
var parts = reference.split(':');
if (parts.length > 1) {
var tl = this.decodeAddress(parts[0]);
var br = this.decodeAddress(parts[1]);
var top = Math.min(tl.row, br.row);
var left = Math.min(tl.col, br.col);
var bottom = Math.max(tl.row, br.row);
var right = Math.max(tl.col, br.col);
tl = this.n2l(left) + top;
br = this.n2l(right) + bottom;
return {
top: top,
left: left,
bottom: bottom,
right: right,
sheetName: sheetName,
tl: { address: tl, col: left, row: top, $col$row: '$' + this.n2l(left) + '$' + top, sheetName: sheetName },
br: { address: br, col: right, row: bottom, $col$row: '$' + this.n2l(right) + '$' + bottom, sheetName: sheetName },
dimensions: tl + ':' + br
};
} else if (reference.startsWith('#')) {
return sheetName ? { sheetName: sheetName, error: reference } : { error: reference };
}
var address = this.decodeAddress(reference);
return sheetName ? Object.assign({ sheetName: sheetName }, address) : address;
},
// convert row,col into address string
encodeAddress: function encodeAddress(row, col) {
return colCache.n2l(col) + row;
},
// convert row,col into string address or t,l,b,r into range
encode: function encode() {
switch (arguments.length) {
case 2:
return colCache.encodeAddress(arguments[0], arguments[1]);
case 4:
return colCache.encodeAddress(arguments[0], arguments[1]) + ':' + colCache.encodeAddress(arguments[2], arguments[3]);
default:
throw new Error('Can only encode with 2 or 4 arguments');
}
}
};
//# sourceMappingURL=col-cache.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,236 @@
'use strict';
var events = require('events');
var PromishLib = require('./promish');
var utils = require('./utils');
// =============================================================================
// FlowControl - Used to slow down streaming to manageable speed
// Implements a subset of Stream.Duplex: pipe() and write()
var FlowControl = module.exports = function (options) {
this.options = options = options || {};
// Buffer queue
this.queue = [];
// Consumer streams
this.pipes = [];
// Down-stream flow-control instances
this.children = [];
// Up-stream flow-control instances
this.parent = options.parent;
// Ensure we don't flush more than once at a time
this.flushing = false;
// determine timeout for flow control delays
if (options.gc) {
var gc = options.gc;
if (gc.getTimeout) {
this.getTimeout = gc.getTimeout;
} else {
// heap size below which we don't bother delaying
var threshold = gc.threshold !== undefined ? gc.threshold : 150000000;
// convert from heapsize to ms timeout
var divisor = gc.divisor !== undefined ? gc.divisor : 500000;
this.getTimeout = function () {
var memory = process.memoryUsage();
var heapSize = memory.heapTotal;
return heapSize < threshold ? 0 : Math.floor(heapSize / divisor);
};
}
} else {
this.getTimeout = null;
}
};
utils.inherits(FlowControl, events.EventEmitter, {
get name() {
return ['FlowControl', this.parent ? 'Child' : 'Root', this.corked ? 'corked' : 'open'].join(' ');
},
get corked() {
// We remain corked while we have children and at least one has data to consume
return this.children.length > 0 && this.children.some(function (child) {
return child.queue && child.queue.length;
});
},
get stem() {
// the decision to stem the incoming data depends on whether the children are corked
// and how many buffers we have backed up
return this.corked || !this.queue || this.queue.length > 2;
},
_write: function _write(dst, data, encoding) {
// Write to a single destination and return a promise
return new PromishLib.Promish(function (resolve, reject) {
dst.write(data, encoding, function (error) {
if (error) {
reject(error);
} else {
resolve();
}
});
});
},
_pipe: function _pipe(chunk) {
var _this = this;
// Write chunk to all pipes. A chunk with no data is the end
var promises = [];
this.pipes.forEach(function (pipe) {
if (chunk.data) {
if (pipe.sync) {
pipe.stream.write(chunk.data, chunk.encoding);
} else {
promises.push(_this._write(pipe.stream, chunk.data, chunk.encoding));
}
} else {
pipe.stream.end();
}
});
if (!promises.length) {
promises.push(PromishLib.Promish.resolve());
}
return PromishLib.Promish.all(promises).then(function () {
try {
chunk.callback();
} catch (e) {
// quietly ignore
}
});
},
_animate: function _animate() {
var count = 0;
var seq = ['|', '/', '-', '\\'];
var cr = '\x1B[0G'; // was '\033[0G'
return setInterval(function () {
process.stdout.write(seq[count++ % 4] + cr);
}, 100);
},
_delay: function _delay() {
var _this2 = this;
// in certain situations it may be useful to delay processing (e.g. for GC)
var timeout = this.getTimeout && this.getTimeout();
if (timeout) {
return new PromishLib.Promish(function (resolve) {
var anime = _this2._animate();
setTimeout(function () {
clearInterval(anime);
resolve();
}, timeout);
});
}
return PromishLib.Promish.resolve();
},
_flush: function _flush() {
var _this3 = this;
// If/while not corked and we have buffers to send, send them
if (this.queue && !this.flushing && !this.corked) {
if (this.queue.length) {
this.flushing = true;
this._delay().then(function () {
return _this3._pipe(_this3.queue.shift());
}).then(function () {
setImmediate(function () {
_this3.flushing = false;
_this3._flush();
});
});
}
if (!this.stem) {
// Signal up-stream that we're ready for more data
this.emit('drain');
}
}
},
write: function write(data, encoding, callback) {
// Called by up-stream pipe
if (encoding instanceof Function) {
callback = encoding;
encoding = 'utf8';
}
callback = callback || utils.nop;
if (!this.queue) {
throw new Error('Cannot write to stream after end');
}
// Always queue chunks and then flush
this.queue.push({
data: data,
encoding: encoding,
callback: callback
});
this._flush();
// restrict further incoming data if we have backed up buffers or
// the children are still busy
var stemFlow = this.corked || this.queue.length > 3;
return !stemFlow;
},
end: function end() {
var _this4 = this;
// Signal from up-stream
this.queue.push({
callback: function callback() {
_this4.queue = null;
_this4.emit('finish');
}
});
this._flush();
},
pipe: function pipe(stream, options) {
options = options || {};
// some streams don't call callbacks
var sync = options.sync || false;
this.pipes.push({
stream: stream,
sync: sync
});
},
unpipe: function unpipe(stream) {
this.pipes = this.pipes.filter(function (pipe) {
return pipe.stream !== stream;
});
},
createChild: function createChild() {
var _this5 = this;
// Create a down-stream flow-control
var options = Object.assign({ parent: this }, this.options);
var child = new FlowControl(options);
this.children.push(child);
child.on('drain', function () {
// a child is ready for more
_this5._flush();
});
child.on('finish', function () {
// One child has finished its stream. Remove it and continue
_this5.children = _this5.children.filter(function (item) {
return item !== child;
});
_this5._flush();
});
return child;
}
});
//# sourceMappingURL=flow-control.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
'use strict';
module.exports = {
Promish: null
};
//# sourceMappingURL=promish.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../lib/utils/promish.js"],"names":["module","exports","Promish"],"mappings":"AAAA;;AAEAA,OAAOC,OAAP,GAAiB;AACfC,WAAS;AADM,CAAjB","file":"promish.js","sourcesContent":["'use strict';\n\nmodule.exports = {\n Promish: null\n};\n"]}

View File

@@ -0,0 +1,44 @@
'use strict';
var colCache = require('./col-cache');
// var cellRefRegex = /(([a-z_\-0-9]*)!)?[$]?([a-z]+)[$]?([1-9][0-9]*)/i;
var replacementCandidateRx = /(([a-z_\-0-9]*)!)?([a-z0-9_$]{2,})([(])?/ig;
var CRrx = /^([$])?([a-z]+)([$])?([1-9][0-9]*)$/i;
var slideFormula = function slideFormula(formula, fromCell, toCell) {
var offset = colCache.decode(fromCell);
var to = colCache.decode(toCell);
return formula.replace(replacementCandidateRx, function (refMatch, sheet, sheetMaybe, addrPart, trailingParen) {
if (trailingParen) {
return refMatch;
}
var match = CRrx.exec(addrPart);
if (match) {
var colDollar = match[1];
var colStr = match[2].toUpperCase();
var rowDollar = match[3];
var rowStr = match[4];
if (colStr.length > 3 || colStr.length === 3 && colStr > 'XFD') {
// > XFD is the highest col number in excel 2007 and beyond, so this is a named range
return refMatch;
}
var col = colCache.l2n(colStr);
var row = parseInt(rowStr, 10);
if (!colDollar) {
col += to.col - offset.col;
}
if (!rowDollar) {
row += to.row - offset.row;
}
var res = (sheet || '') + (colDollar || '') + colCache.n2l(col) + (rowDollar || '') + row;
return res;
}
return refMatch;
});
};
module.exports = {
slideFormula: slideFormula
};
//# sourceMappingURL=shared-formula.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../lib/utils/shared-formula.js"],"names":["colCache","require","replacementCandidateRx","CRrx","slideFormula","formula","fromCell","toCell","offset","decode","to","replace","refMatch","sheet","sheetMaybe","addrPart","trailingParen","match","exec","colDollar","colStr","toUpperCase","rowDollar","rowStr","length","col","l2n","row","parseInt","res","n2l","module","exports"],"mappings":"AAAA;;AAEA,IAAIA,WAAWC,QAAQ,aAAR,CAAf;;AAEA;AACA,IAAIC,yBAAyB,4CAA7B;AACA,IAAIC,OAAO,sCAAX;;AAEA,IAAIC,eAAe,SAAfA,YAAe,CAASC,OAAT,EAAkBC,QAAlB,EAA4BC,MAA5B,EAAoC;AACrD,MAAIC,SAASR,SAASS,MAAT,CAAgBH,QAAhB,CAAb;AACA,MAAII,KAAKV,SAASS,MAAT,CAAgBF,MAAhB,CAAT;AACA,SAAOF,QAAQM,OAAR,CAAgBT,sBAAhB,EAAwC,UAASU,QAAT,EAAmBC,KAAnB,EAA0BC,UAA1B,EAAsCC,QAAtC,EAAgDC,aAAhD,EAA+D;AAC5G,QAAIA,aAAJ,EAAmB;AACjB,aAAOJ,QAAP;AACD;AACD,QAAIK,QAAQd,KAAKe,IAAL,CAAUH,QAAV,CAAZ;AACA,QAAIE,KAAJ,EAAW;AACT,UAAIE,YAAYF,MAAM,CAAN,CAAhB;AACA,UAAIG,SAASH,MAAM,CAAN,EAASI,WAAT,EAAb;AACA,UAAIC,YAAYL,MAAM,CAAN,CAAhB;AACA,UAAIM,SAASN,MAAM,CAAN,CAAb;AACA,UAAIG,OAAOI,MAAP,GAAgB,CAAhB,IAAsBJ,OAAOI,MAAP,KAAkB,CAAlB,IAAuBJ,SAAS,KAA1D,EAAkE;AAChE;AACA,eAAOR,QAAP;AACD;AACD,UAAIa,MAAMzB,SAAS0B,GAAT,CAAaN,MAAb,CAAV;AACA,UAAIO,MAAMC,SAASL,MAAT,EAAiB,EAAjB,CAAV;AACA,UAAI,CAACJ,SAAL,EAAgB;AACdM,eAAOf,GAAGe,GAAH,GAASjB,OAAOiB,GAAvB;AACD;AACD,UAAI,CAACH,SAAL,EAAgB;AACdK,eAAOjB,GAAGiB,GAAH,GAASnB,OAAOmB,GAAvB;AACD;AACD,UAAIE,MAAM,CAAChB,SAAS,EAAV,KAAiBM,aAAa,EAA9B,IAAoCnB,SAAS8B,GAAT,CAAaL,GAAb,CAApC,IAAyDH,aAAa,EAAtE,IAA4EK,GAAtF;AACA,aAAOE,GAAP;AACD;AACD,WAAOjB,QAAP;AACD,GA1BM,CAAP;AA2BD,CA9BD;;AAgCAmB,OAAOC,OAAP,GAAiB;AACf5B;AADe,CAAjB","file":"shared-formula.js","sourcesContent":["'use strict';\n\nvar colCache = require('./col-cache');\n\n// var cellRefRegex = /(([a-z_\\-0-9]*)!)?[$]?([a-z]+)[$]?([1-9][0-9]*)/i;\nvar replacementCandidateRx = /(([a-z_\\-0-9]*)!)?([a-z0-9_$]{2,})([(])?/ig;\nvar CRrx = /^([$])?([a-z]+)([$])?([1-9][0-9]*)$/i;\n\nvar slideFormula = function(formula, fromCell, toCell) {\n var offset = colCache.decode(fromCell);\n var to = colCache.decode(toCell);\n return formula.replace(replacementCandidateRx, function(refMatch, sheet, sheetMaybe, addrPart, trailingParen) {\n if (trailingParen) {\n return refMatch;\n }\n var match = CRrx.exec(addrPart);\n if (match) {\n var colDollar = match[1];\n var colStr = match[2].toUpperCase();\n var rowDollar = match[3];\n var rowStr = match[4];\n if (colStr.length > 3 || (colStr.length === 3 && colStr > 'XFD')) {\n // > XFD is the highest col number in excel 2007 and beyond, so this is a named range\n return refMatch;\n }\n var col = colCache.l2n(colStr);\n var row = parseInt(rowStr, 10);\n if (!colDollar) {\n col += to.col - offset.col;\n }\n if (!rowDollar) {\n row += to.row - offset.row;\n }\n var res = (sheet || '') + (colDollar || '') + colCache.n2l(col) + (rowDollar || '') + row;\n return res;\n }\n return refMatch;\n });\n};\n\nmodule.exports = {\n slideFormula\n};\n"]}

View File

@@ -0,0 +1,34 @@
'use strict';
var SharedStrings = module.exports = function () {
this._values = [];
this._totalRefs = 0;
this._hash = {};
};
SharedStrings.prototype = {
get count() {
return this._values.length;
},
get values() {
return this._values;
},
get totalRefs() {
return this._totalRefs;
},
getString: function getString(index) {
return this._values[index];
},
add: function add(value) {
var index = this._hash[value];
if (index === undefined) {
index = this._hash[value] = this._values.length;
this._values.push(value);
}
this._totalRefs++;
return index;
}
};
//# sourceMappingURL=shared-strings.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../lib/utils/shared-strings.js"],"names":["SharedStrings","module","exports","_values","_totalRefs","_hash","prototype","count","length","values","totalRefs","getString","index","add","value","undefined","push"],"mappings":"AAAA;;AAEA,IAAIA,gBAAgBC,OAAOC,OAAP,GAAiB,YAAW;AAC9C,OAAKC,OAAL,GAAe,EAAf;AACA,OAAKC,UAAL,GAAkB,CAAlB;AACA,OAAKC,KAAL,GAAa,EAAb;AACD,CAJD;;AAMAL,cAAcM,SAAd,GAA0B;AACxB,MAAIC,KAAJ,GAAY;AACV,WAAO,KAAKJ,OAAL,CAAaK,MAApB;AACD,GAHuB;AAIxB,MAAIC,MAAJ,GAAa;AACX,WAAO,KAAKN,OAAZ;AACD,GANuB;AAOxB,MAAIO,SAAJ,GAAgB;AACd,WAAO,KAAKN,UAAZ;AACD,GATuB;;AAWxBO,aAAW,mBAASC,KAAT,EAAgB;AACzB,WAAO,KAAKT,OAAL,CAAaS,KAAb,CAAP;AACD,GAbuB;;AAexBC,OAAK,aAASC,KAAT,EAAgB;AACnB,QAAIF,QAAQ,KAAKP,KAAL,CAAWS,KAAX,CAAZ;AACA,QAAIF,UAAUG,SAAd,EAAyB;AACvBH,cAAQ,KAAKP,KAAL,CAAWS,KAAX,IAAoB,KAAKX,OAAL,CAAaK,MAAzC;AACA,WAAKL,OAAL,CAAaa,IAAb,CAAkBF,KAAlB;AACD;AACD,SAAKV,UAAL;AACA,WAAOQ,KAAP;AACD;AAvBuB,CAA1B","file":"shared-strings.js","sourcesContent":["'use strict';\n\nvar SharedStrings = module.exports = function() {\n this._values = [];\n this._totalRefs = 0;\n this._hash = {};\n};\n\nSharedStrings.prototype = {\n get count() {\n return this._values.length;\n },\n get values() {\n return this._values;\n },\n get totalRefs() {\n return this._totalRefs;\n },\n\n getString: function(index) {\n return this._values[index];\n },\n\n add: function(value) {\n var index = this._hash[value];\n if (index === undefined) {\n index = this._hash[value] = this._values.length;\n this._values.push(value);\n }\n this._totalRefs++;\n return index;\n }\n};\n"]}

View File

@@ -0,0 +1,63 @@
'use strict';
var Stream = require('stream');
var utils = require('./utils');
// =============================================================================
// StreamBase64 - A utility to convert to/from base64 stream
// Note: does not buffer data, must be piped
var StreamBuf = module.exports = function () {
// consuming pipe streams go here
this.pipes = [];
};
utils.inherits(StreamBuf, Stream.Duplex, {
// writable
// event drain - if write returns false (which it won't), indicates when safe to write again.
// finish - end() has been called
// pipe(src) - pipe() has been called on readable
// unpipe(src) - unpipe() has been called on readable
// error - duh
write: function write() /* data, encoding */{
return true;
},
cork: function cork() {},
uncork: function uncork() {},
end: function end() /* chunk, encoding, callback */{},
// readable
// event readable - some data is now available
// event data - switch to flowing mode - feeds chunks to handler
// event end - no more data
// event close - optional, indicates upstream close
// event error - duh
read: function read() /* size */{},
setEncoding: function setEncoding(encoding) {
// causes stream.read or stream.on('data) to return strings of encoding instead of Buffer objects
this.encoding = encoding;
},
pause: function pause() {},
resume: function resume() {},
isPaused: function isPaused() {},
pipe: function pipe(destination) {
// add destination to pipe list & write current buffer
this.pipes.push(destination);
},
unpipe: function unpipe(destination) {
// remove destination from pipe list
this.pipes = this.pipes.filter(function (pipe) {
return pipe !== destination;
});
},
unshift: function unshift() /* chunk */{
// some numpty has read some data that's not for them and they want to put it back!
// Might implement this some day
throw new Error('Not Implemented');
},
wrap: function wrap() /* stream */{
// not implemented
throw new Error('Not Implemented');
}
});
//# sourceMappingURL=stream-base64.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../lib/utils/stream-base64.js"],"names":["Stream","require","utils","StreamBuf","module","exports","pipes","inherits","Duplex","write","cork","uncork","end","read","setEncoding","encoding","pause","resume","isPaused","pipe","destination","push","unpipe","filter","unshift","Error","wrap"],"mappings":"AAAA;;AAEA,IAAIA,SAASC,QAAQ,QAAR,CAAb;AACA,IAAIC,QAAQD,QAAQ,SAAR,CAAZ;;AAEA;AACA;AACA;AACA,IAAIE,YAAYC,OAAOC,OAAP,GAAiB,YAAW;AAC1C;AACA,OAAKC,KAAL,GAAa,EAAb;AACD,CAHD;;AAKAJ,MAAMK,QAAN,CAAeJ,SAAf,EAA0BH,OAAOQ,MAAjC,EAAyC;AACvC;AACA;AACA;AACA;AACA;AACA;;AAEAC,SAAO,iBAAS,oBAAsB;AACpC,WAAO,IAAP;AACD,GAVsC;AAWvCC,QAAM,gBAAW,CAChB,CAZsC;AAavCC,UAAQ,kBAAW,CAClB,CAdsC;AAevCC,OAAK,eAAS,+BAAiC,CAC9C,CAhBsC;;AAkBvC;AACA;AACA;AACA;AACA;AACA;AACAC,QAAM,gBAAS,UAAY,CAC1B,CAzBsC;AA0BvCC,eAAa,qBAASC,QAAT,EAAmB;AAC9B;AACA,SAAKA,QAAL,GAAgBA,QAAhB;AACD,GA7BsC;AA8BvCC,SAAO,iBAAW,CACjB,CA/BsC;AAgCvCC,UAAQ,kBAAW,CAClB,CAjCsC;AAkCvCC,YAAU,oBAAW,CACpB,CAnCsC;AAoCvCC,QAAM,cAASC,WAAT,EAAsB;AAC1B;AACA,SAAKd,KAAL,CAAWe,IAAX,CAAgBD,WAAhB;AACD,GAvCsC;AAwCvCE,UAAQ,gBAASF,WAAT,EAAsB;AAC5B;AACA,SAAKd,KAAL,GAAa,KAAKA,KAAL,CAAWiB,MAAX,CAAkB,UAASJ,IAAT,EAAe;AAC5C,aAAOA,SAASC,WAAhB;AACD,KAFY,CAAb;AAGD,GA7CsC;AA8CvCI,WAAS,mBAAS,WAAa;AAC7B;AACA;AACA,UAAM,IAAIC,KAAJ,CAAU,iBAAV,CAAN;AACD,GAlDsC;AAmDvCC,QAAM,gBAAS,YAAc;AAC3B;AACA,UAAM,IAAID,KAAJ,CAAU,iBAAV,CAAN;AACD;AAtDsC,CAAzC","file":"stream-base64.js","sourcesContent":["'use strict';\n\nvar Stream = require('stream');\nvar utils = require('./utils');\n\n// =============================================================================\n// StreamBase64 - A utility to convert to/from base64 stream\n// Note: does not buffer data, must be piped\nvar StreamBuf = module.exports = function() {\n // consuming pipe streams go here\n this.pipes = [];\n};\n\nutils.inherits(StreamBuf, Stream.Duplex, {\n // writable\n // event drain - if write returns false (which it won't), indicates when safe to write again.\n // finish - end() has been called\n // pipe(src) - pipe() has been called on readable\n // unpipe(src) - unpipe() has been called on readable\n // error - duh\n\n write: function(/* data, encoding */) {\n return true;\n },\n cork: function() {\n },\n uncork: function() {\n },\n end: function(/* chunk, encoding, callback */) {\n },\n\n // readable\n // event readable - some data is now available\n // event data - switch to flowing mode - feeds chunks to handler\n // event end - no more data\n // event close - optional, indicates upstream close\n // event error - duh\n read: function(/* size */) {\n },\n setEncoding: function(encoding) {\n // causes stream.read or stream.on('data) to return strings of encoding instead of Buffer objects\n this.encoding = encoding;\n },\n pause: function() {\n },\n resume: function() {\n },\n isPaused: function() {\n },\n pipe: function(destination) {\n // add destination to pipe list & write current buffer\n this.pipes.push(destination);\n },\n unpipe: function(destination) {\n // remove destination from pipe list\n this.pipes = this.pipes.filter(function(pipe) {\n return pipe !== destination;\n });\n },\n unshift: function(/* chunk */) {\n // some numpty has read some data that's not for them and they want to put it back!\n // Might implement this some day\n throw new Error('Not Implemented');\n },\n wrap: function(/* stream */) {\n // not implemented\n throw new Error('Not Implemented');\n }\n});\n"]}

View File

@@ -0,0 +1,353 @@
'use strict';
var Stream = require('stream');
var PromishLib = require('./promish');
var utils = require('./utils');
var StringBuf = require('./string-buf');
// =============================================================================
// data chunks - encapsulating incoming data
var StringChunk = function StringChunk(data, encoding) {
this._data = data;
this._encoding = encoding;
};
StringChunk.prototype = {
get length() {
return this.toBuffer().length;
},
// copy to target buffer
copy: function copy(target, targetOffset, offset, length) {
return this.toBuffer().copy(target, targetOffset, offset, length);
},
toBuffer: function toBuffer() {
if (!this._buffer) {
this._buffer = new Buffer(this._data, this._encoding);
}
return this._buffer;
}
};
var StringBufChunk = function StringBufChunk(data) {
this._data = data;
};
StringBufChunk.prototype = {
get length() {
return this._data.length;
},
// copy to target buffer
copy: function copy(target, targetOffset, offset, length) {
// eslint-disable-next-line no-underscore-dangle
return this._data._buf.copy(target, targetOffset, offset, length);
},
toBuffer: function toBuffer() {
return this._data.toBuffer();
}
};
var BufferChunk = function BufferChunk(data) {
this._data = data;
};
BufferChunk.prototype = {
get length() {
return this._data.length;
},
// copy to target buffer
copy: function copy(target, targetOffset, offset, length) {
this._data.copy(target, targetOffset, offset, length);
},
toBuffer: function toBuffer() {
return this._data;
}
};
// =============================================================================
// ReadWriteBuf - a single buffer supporting simple read-write
var ReadWriteBuf = function ReadWriteBuf(size) {
this.size = size;
// the buffer
this.buffer = new Buffer(size);
// read index
this.iRead = 0;
// write index
this.iWrite = 0;
};
ReadWriteBuf.prototype = {
toBuffer: function toBuffer() {
if (this.iRead === 0 && this.iWrite === this.size) {
return this.buffer;
}
var buf = new Buffer(this.iWrite - this.iRead);
this.buffer.copy(buf, 0, this.iRead, this.iWrite);
return buf;
},
get length() {
return this.iWrite - this.iRead;
},
get eod() {
return this.iRead === this.iWrite;
},
get full() {
return this.iWrite === this.size;
},
read: function read(size) {
var buf;
// read size bytes from buffer and return buffer
if (size === 0) {
// special case - return null if no data requested
return null;
}
if (size === undefined || size >= this.length) {
// if no size specified or size is at least what we have then return all of the bytes
buf = this.toBuffer();
this.iRead = this.iWrite;
return buf;
}
// otherwise return a chunk
buf = new Buffer(size);
this.buffer.copy(buf, 0, this.iRead, size);
this.iRead += size;
return buf;
},
write: function write(chunk, offset, length) {
// write as many bytes from data from optional source offset
// and return number of bytes written
var size = Math.min(length, this.size - this.iWrite);
chunk.copy(this.buffer, this.iWrite, offset, offset + size);
this.iWrite += size;
return size;
}
};
// =============================================================================
// StreamBuf - a multi-purpose read-write stream
// As MemBuf - write as much data as you like. Then call toBuffer() to consolidate
// As StreamHub - pipe to multiple writables
// As readable stream - feed data into the writable part and have some other code read from it.
var StreamBuf = module.exports = function (options) {
options = options || {};
this.bufSize = options.bufSize || 1024 * 1024;
this.buffers = [];
// batch mode fills a buffer completely before passing the data on
// to pipes or 'readable' event listeners
this.batch = options.batch || false;
this.corked = false;
// where in the current writable buffer we're up to
this.inPos = 0;
// where in the current readable buffer we've read up to
this.outPos = 0;
// consuming pipe streams go here
this.pipes = [];
// controls emit('data')
this.paused = false;
this.encoding = null;
};
utils.inherits(StreamBuf, Stream.Duplex, {
toBuffer: function toBuffer() {
switch (this.buffers.length) {
case 0:
return null;
case 1:
return this.buffers[0].toBuffer();
default:
return Buffer.concat(this.buffers.map(function (rwBuf) {
return rwBuf.toBuffer();
}));
}
},
// writable
// event drain - if write returns false (which it won't), indicates when safe to write again.
// finish - end() has been called
// pipe(src) - pipe() has been called on readable
// unpipe(src) - unpipe() has been called on readable
// error - duh
_getWritableBuffer: function _getWritableBuffer() {
if (this.buffers.length) {
var last = this.buffers[this.buffers.length - 1];
if (!last.full) {
return last;
}
}
var buf = new ReadWriteBuf(this.bufSize);
this.buffers.push(buf);
return buf;
},
_pipe: function _pipe(chunk) {
var write = function write(pipe) {
return new PromishLib.Promish(function (resolve) {
pipe.write(chunk.toBuffer(), function () {
resolve();
});
});
};
var promises = this.pipes.map(write);
return promises.length ? PromishLib.Promish.all(promises).then(utils.nop) : PromishLib.Promish.resolve();
},
_writeToBuffers: function _writeToBuffers(chunk) {
var inPos = 0;
var inLen = chunk.length;
while (inPos < inLen) {
// find writable buffer
var buffer = this._getWritableBuffer();
// write some data
inPos += buffer.write(chunk, inPos, inLen - inPos);
}
},
write: function write(data, encoding, callback) {
if (encoding instanceof Function) {
callback = encoding;
encoding = 'utf8';
}
callback = callback || utils.nop;
// encapsulate data into a chunk
var chunk;
if (data instanceof StringBuf) {
chunk = new StringBufChunk(data);
} else if (data instanceof Buffer) {
chunk = new BufferChunk(data);
} else {
// assume string
chunk = new StringChunk(data, encoding);
}
// now, do something with the chunk
if (this.pipes.length) {
if (this.batch) {
this._writeToBuffers(chunk);
while (!this.corked && this.buffers.length > 1) {
this._pipe(this.buffers.shift());
}
} else if (!this.corked) {
this._pipe(chunk).then(callback);
} else {
this._writeToBuffers(chunk);
process.nextTick(callback);
}
} else {
if (!this.paused) {
this.emit('data', chunk.toBuffer());
}
this._writeToBuffers(chunk);
this.emit('readable');
}
return true;
},
cork: function cork() {
this.corked = true;
},
_flush: function _flush() /* destination */{
// if we have comsumers...
if (this.pipes.length) {
// and there's stuff not written
while (this.buffers.length) {
this._pipe(this.buffers.shift());
}
}
},
uncork: function uncork() {
this.corked = false;
this._flush();
},
end: function end(chunk, encoding, callback) {
var _this = this;
var writeComplete = function writeComplete(error) {
if (error) {
callback(error);
} else {
_this._flush();
_this.pipes.forEach(function (pipe) {
pipe.end();
});
_this.emit('finish');
}
};
if (chunk) {
this.write(chunk, encoding, writeComplete);
} else {
writeComplete();
}
},
// readable
// event readable - some data is now available
// event data - switch to flowing mode - feeds chunks to handler
// event end - no more data
// event close - optional, indicates upstream close
// event error - duh
read: function read(size) {
var buffers;
// read min(buffer, size || infinity)
if (size) {
buffers = [];
while (size && this.buffers.length && !this.buffers[0].eod) {
var first = this.buffers[0];
var buffer = first.read(size);
size -= buffer.length;
buffers.push(buffer);
if (first.eod && first.full) {
this.buffers.shift();
}
}
return Buffer.concat(buffers);
}
buffers = this.buffers.map(function (buf) {
return buf.toBuffer();
}).filter(Boolean);
this.buffers = [];
return Buffer.concat(buffers);
},
setEncoding: function setEncoding(encoding) {
// causes stream.read or stream.on('data) to return strings of encoding instead of Buffer objects
this.encoding = encoding;
},
pause: function pause() {
this.paused = true;
},
resume: function resume() {
this.paused = false;
},
isPaused: function isPaused() {
return !!this.paused;
},
pipe: function pipe(destination) {
// add destination to pipe list & write current buffer
this.pipes.push(destination);
if (!this.paused && this.buffers.length) {
this.end();
}
},
unpipe: function unpipe(destination) {
// remove destination from pipe list
this.pipes = this.pipes.filter(function (pipe) {
return pipe !== destination;
});
},
unshift: function unshift() /* chunk */{
// some numpty has read some data that's not for them and they want to put it back!
// Might implement this some day
throw new Error('Not Implemented');
},
wrap: function wrap() /* stream */{
// not implemented
throw new Error('Not Implemented');
}
});
//# sourceMappingURL=stream-buf.js.map

Some files were not shown because too many files have changed in this diff Show More