You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1313 lines
43 KiB
1313 lines
43 KiB
import { ActionIcon, Button, Flex, Group, Input, Stack, Text, TextInput } from "@mantine/core"
|
|
import { useEffect, useState } from "react"
|
|
import createReport, { listCommands } from 'docx-templates'
|
|
import { Dropzone, DropzoneProps, IMAGE_MIME_TYPE, MS_WORD_MIME_TYPE } from '@mantine/dropzone'
|
|
import { IconFile, IconFileTypeDocx, IconPhoto, IconPlus, IconUpload, IconX } from "@tabler/icons-react"
|
|
import { CommandSummary } from "docx-templates/lib/types"
|
|
import { Control, Controller, FieldValues, SubmitHandler, useFieldArray, useForm, UseFormRegister } from "react-hook-form"
|
|
import { TemplateHandler } from 'easy-template-x'
|
|
|
|
const xslTemplate = `<?xml version="1.0" encoding="utf-8"?>
|
|
<xsl:stylesheet version="1.0" xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
|
<!-- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Шаблон >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
|
<xsl:template match="/">
|
|
<xsl:processing-instruction name="mso-application">
|
|
<xsl:text>progid="Excel.Sheet"</xsl:text>
|
|
</xsl:processing-instruction>
|
|
<Workbook>
|
|
<!-- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Стили шаблона >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
|
<Styles>
|
|
<Style ss:ID="Bordered1">
|
|
<Borders>
|
|
<Border ss:LineStyle="Continuous" ss:Position="Bottom" ss:Weight="1" />
|
|
<Border ss:LineStyle="Continuous" ss:Position="Left" ss:Weight="1" />
|
|
<Border ss:LineStyle="Continuous" ss:Position="Right" ss:Weight="1" />
|
|
<Border ss:LineStyle="Continuous" ss:Position="Top" ss:Weight="1" />
|
|
</Borders>
|
|
</Style>
|
|
<Style ss:ID="Bordered2">
|
|
<Borders>
|
|
<Border ss:LineStyle="Continuous" ss:Position="Bottom" ss:Weight="2" />
|
|
<Border ss:LineStyle="Continuous" ss:Position="Left" ss:Weight="2" />
|
|
<Border ss:LineStyle="Continuous" ss:Position="Right" ss:Weight="2" />
|
|
<Border ss:LineStyle="Continuous" ss:Position="Top" ss:Weight="2" />
|
|
</Borders>
|
|
</Style>
|
|
<Style ss:ID="Column" ss:Parent="Bordered2">
|
|
<Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1" />
|
|
<Font ss:Color="#000000" ss:FontName="Arial Cyr" x:CharSet="204" />
|
|
</Style>
|
|
<Style ss:ID="Cell1" ss:Parent="Bordered1">
|
|
<Font ss:Bold="1" ss:Color="#000000" ss:FontName="Arial Cyr" x:CharSet="204" />
|
|
<Interior ss:Color="#47FF19" ss:Pattern="Solid" />
|
|
</Style>
|
|
<Style ss:ID="Cell2" ss:Parent="Bordered1">
|
|
<Font ss:Bold="1" ss:Color="#003366" ss:FontName="Arial Cyr" x:CharSet="204" />
|
|
<Interior ss:Color="#F2FF02" ss:Pattern="Solid" />
|
|
</Style>
|
|
<Style ss:ID="Cell3" ss:Parent="Bordered1">
|
|
<Font ss:Bold="1" ss:Color="#333333" ss:FontName="Arial Cyr" x:CharSet="204" />
|
|
<Interior ss:Color="#C0C0C0" ss:Pattern="Solid" />
|
|
</Style>
|
|
<Style ss:ID="Cell4" ss:Parent="Bordered1">
|
|
<Font ss:Color="#000000" ss:FontName="Arial Cyr" x:CharSet="204" />
|
|
</Style>
|
|
|
|
<Style ss:ID="CellReg" ss:Parent="Bordered1">
|
|
<Font ss:Color="#003366" ss:FontName="Arial Cyr" x:CharSet="204" />
|
|
|
|
</Style>
|
|
<Style ss:ID="CellCity" ss:Parent="Bordered1">
|
|
<Font ss:Color="#333333" ss:FontName="Arial Cyr" x:CharSet="204" />
|
|
|
|
</Style>
|
|
</Styles>
|
|
<Worksheet ss:Name="Жилищний фонд">
|
|
<Table>
|
|
<Column ss:Width="100" />
|
|
<Column ss:Width="100" />
|
|
<Column ss:Width="100" />
|
|
<Column ss:Width="150" />
|
|
<Column ss:Width="50" />
|
|
<Column ss:Width="50" />
|
|
<Column ss:Width="50" />
|
|
<Column ss:Width="50" />
|
|
<Column ss:Width="70" />
|
|
<Column ss:Width="70" />
|
|
<Column ss:Width="70" />
|
|
<Column ss:Width="70" />
|
|
<Column ss:Width="70" />
|
|
<Column ss:Width="70" />
|
|
<Column ss:Width="70" />
|
|
<Column ss:Width="70" />
|
|
<Column ss:Width="80" />
|
|
<!-- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Столбцы таблицы >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
|
<Row>
|
|
<Cell ss:MergeDown="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Регион</Data>
|
|
</Cell>
|
|
<Cell ss:MergeDown="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Нас. пункт</Data>
|
|
</Cell>
|
|
<Cell ss:MergeDown="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Котельная</Data>
|
|
</Cell>
|
|
<Cell ss:MergeDown="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Адрес</Data>
|
|
</Cell>
|
|
<Cell ss:MergeDown="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Кол-во домов</Data>
|
|
</Cell>
|
|
<Cell ss:MergeDown="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Этаж.</Data>
|
|
</Cell>
|
|
<Cell ss:MergeDown="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Общая пл.</Data>
|
|
</Cell>
|
|
<Cell ss:MergeDown="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Кол-во прожив.</Data>
|
|
</Cell>
|
|
<Cell ss:MergeAcross="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Отопление</Data>
|
|
</Cell>
|
|
<Cell ss:MergeAcross="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">ГВС</Data>
|
|
</Cell>
|
|
<Cell ss:MergeAcross="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">ХВС</Data>
|
|
</Cell>
|
|
<Cell ss:MergeAcross="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Канализация</Data>
|
|
</Cell>
|
|
<Cell ss:MergeDown="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Сальдо исход.</Data>
|
|
</Cell>
|
|
</Row>
|
|
<Row>
|
|
<Cell ss:Index="9" ss:StyleID="Column">
|
|
<Data ss:Type="String">Объем</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Column">
|
|
<Data ss:Type="String">Сумма</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Column">
|
|
<Data ss:Type="String">Объем</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Column">
|
|
<Data ss:Type="String">Сумма</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Column">
|
|
<Data ss:Type="String">Объем</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Column">
|
|
<Data ss:Type="String">Сумма</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Column">
|
|
<Data ss:Type="String">Объем</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Column">
|
|
<Data ss:Type="String">Сумма</Data>
|
|
</Cell>
|
|
</Row>
|
|
<!-- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Данные таблицы >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
|
<xsl:apply-templates select="//Kvp" />
|
|
</Table>
|
|
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
|
|
<FreezePanes />
|
|
<FrozenNoSplit />
|
|
<SplitHorizontal>2</SplitHorizontal>
|
|
<TopRowBottomPane>2</TopRowBottomPane>
|
|
<ActivePane>2</ActivePane>
|
|
</WorksheetOptions>
|
|
</Worksheet>
|
|
<Worksheet ss:Name="Договорные подключения">
|
|
<Table>
|
|
<Column ss:Width="100" />
|
|
<Column ss:Width="100" />
|
|
<Column ss:Width="100" />
|
|
<Column ss:Width="150" />
|
|
<Column ss:Width="50" />
|
|
<Column ss:Width="50" />
|
|
<Column ss:Width="50" />
|
|
<Column ss:Width="50" />
|
|
<Column ss:Width="50" />
|
|
<Column ss:Width="50" />
|
|
<Column ss:Width="50" />
|
|
<Column ss:Width="50" />
|
|
<Column ss:Width="50" />
|
|
<Column ss:Width="50" />
|
|
<Column ss:Width="70" />
|
|
<!-- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Столбцы таблицы >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
|
<Row>
|
|
<Cell ss:MergeDown="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Регион</Data>
|
|
</Cell>
|
|
<Cell ss:MergeDown="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Нас. пункт</Data>
|
|
</Cell>
|
|
<Cell ss:MergeDown="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Котельная</Data>
|
|
</Cell>
|
|
<Cell ss:MergeDown="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Наименование</Data>
|
|
</Cell>
|
|
<Cell ss:MergeDown="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Кол-во объектов</Data>
|
|
</Cell>
|
|
<Cell ss:MergeDown="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Объем здания</Data>
|
|
</Cell>
|
|
<Cell ss:MergeAcross="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Отопление</Data>
|
|
</Cell>
|
|
<Cell ss:MergeAcross="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Подогрев</Data>
|
|
</Cell>
|
|
<Cell ss:MergeAcross="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">ГВС</Data>
|
|
</Cell>
|
|
<Cell ss:MergeAcross="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">ХВС</Data>
|
|
</Cell>
|
|
<Cell ss:MergeAcross="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Канализация</Data>
|
|
</Cell>
|
|
<Cell ss:MergeDown="1" ss:StyleID="Column">
|
|
<Data ss:Type="String">Итого</Data>
|
|
</Cell>
|
|
</Row>
|
|
<Row>
|
|
<Cell ss:Index="7" ss:StyleID="Column">
|
|
<Data ss:Type="String">Объем</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Column">
|
|
<Data ss:Type="String">Сумма</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Column">
|
|
<Data ss:Type="String">Объем</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Column">
|
|
<Data ss:Type="String">Сумма</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Column">
|
|
<Data ss:Type="String">Объем</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Column">
|
|
<Data ss:Type="String">Сумма</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Column">
|
|
<Data ss:Type="String">Объем</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Column">
|
|
<Data ss:Type="String">Сумма</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Column">
|
|
<Data ss:Type="String">Объем</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Column">
|
|
<Data ss:Type="String">Сумма</Data>
|
|
</Cell>
|
|
</Row>
|
|
<!-- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Данные таблицы >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
|
<xsl:apply-templates select="//Jur" />
|
|
</Table>
|
|
</Worksheet>
|
|
</Workbook>
|
|
</xsl:template>
|
|
<!-- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Шаблон данных >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
|
<xsl:template match="Kvp">
|
|
<xsl:choose>
|
|
<xsl:when test="style_id = 1">
|
|
<!-- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Строка с улусом >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
|
<Row>
|
|
<Cell ss:MergeAcross="3" ss:StyleID="Cell1">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="region" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="house_count" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="String" />
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="square" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="people_count" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="volume_heat" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_heat" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="volume_hwater" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_hwater" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="volume_cwater" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_cwater" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="volume_sewers" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_sewers" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="saldo_out" />
|
|
</Data>
|
|
</Cell>
|
|
</Row>
|
|
</xsl:when>
|
|
<xsl:when test="style_id = 2">
|
|
<!-- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Строка с населенным пунктом >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
|
<Row>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="region" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:Index="2" ss:MergeAcross="2" ss:StyleID="Cell2">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="city" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="house_count" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="String" />
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="square" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="people_count" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="volume_heat" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_heat" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="volume_hwater" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_hwater" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="volume_cwater" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_cwater" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="volume_sewers" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_sewers" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="saldo_out" />
|
|
</Data>
|
|
</Cell>
|
|
</Row>
|
|
</xsl:when>
|
|
<xsl:when test="style_id = 3">
|
|
<!-- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Строка с котельной >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
|
<Row>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="region" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="city" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:Index="3" ss:MergeAcross="1" ss:StyleID="Cell3">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="boiler" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="house_count" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="String" />
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="square" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="people_count" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="volume_heat" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_heat" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="volume_hwater" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_hwater" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="volume_cwater" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_cwater" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="volume_sewers" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_sewers" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="saldo_out" />
|
|
</Data>
|
|
</Cell>
|
|
</Row>
|
|
</xsl:when>
|
|
<xsl:when test="style_id = 4">
|
|
<!-- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Строка с объектами >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
|
<Row>
|
|
<Cell ss:StyleID="CellReg">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="region" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:Index="2" ss:StyleID="CellCity">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="city" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:Index="3" ss:StyleID="Cell3">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="boiler" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:MergeAcross="1" ss:Index="4" ss:StyleID="Cell4">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="address" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="floors" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="square" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="people_count" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="volume_heat" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_heat" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="volume_hwater" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_hwater" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="volume_cwater" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_cwater" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="volume_sewers" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_sewers" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="saldo_out" />
|
|
</Data>
|
|
</Cell>
|
|
</Row>
|
|
</xsl:when>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
<xsl:template match="Jur">
|
|
<xsl:choose>
|
|
<xsl:when test="style_id = 1">
|
|
<!-- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Строка с улусом >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
|
<Row>
|
|
<Cell ss:MergeAcross="3" ss:StyleID="Cell1">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="reg" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="count" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="building_volume" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="heat_volume" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="heat_summa" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="gcal_ost" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="gcal_ost_summa" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="hw_vol" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="hw_summa" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="vol_xvs" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_xvs" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="vol_kan" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_kan" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell1">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="all_summa" />
|
|
</Data>
|
|
</Cell>
|
|
</Row>
|
|
</xsl:when>
|
|
<xsl:when test="style_id = 2">
|
|
<!-- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Строка с населенным пунктом >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
|
<Row>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="reg" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:Index="2" ss:MergeAcross="2" ss:StyleID="Cell2">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="city" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="count" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="building_volume" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="heat_volume" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="heat_summa" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="gcal_ost" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="gcal_ost_summa" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="hw_vol" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="hw_summa" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="vol_xvs" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_xvs" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="vol_kan" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_kan" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell2">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="all_summa" />
|
|
</Data>
|
|
</Cell>
|
|
</Row>
|
|
</xsl:when>
|
|
<xsl:when test="style_id = 3">
|
|
<!-- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Строка с котельной >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
|
<Row>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="reg" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="city" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:Index="3" ss:MergeAcross="1" ss:StyleID="Cell3">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="boiler" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="count" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="building_volume" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="heat_volume" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="heat_summa" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="gcal_ost" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="gcal_ost_summa" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="hw_vol" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="hw_summa" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="vol_xvs" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_xvs" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="vol_kan" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_kan" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell3">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="all_summa" />
|
|
</Data>
|
|
</Cell>
|
|
</Row>
|
|
</xsl:when>
|
|
<xsl:when test="style_id = 4">
|
|
<!-- <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Строка с объектами >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
|
|
<Row>
|
|
<Cell ss:StyleID="CellReg">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="reg" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:Index="2" ss:StyleID="CellCity">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="city" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:Index="3" ss:StyleID="Cell3">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="boiler" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:MergeAcross="1" ss:Index="4" ss:StyleID="Cell4">
|
|
<Data ss:Type="String">
|
|
<xsl:value-of select="name" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="building_volume" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="heat_volume" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="heat_summa" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="gcal_ost" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="gcal_ost_summa" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="hw_vol" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="hw_summa" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="vol_xvs" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_xvs" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="vol_kan" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="sum_kan" />
|
|
</Data>
|
|
</Cell>
|
|
<Cell ss:StyleID="Cell4">
|
|
<Data ss:Type="Number">
|
|
<xsl:value-of select="all_summa" />
|
|
</Data>
|
|
</Cell>
|
|
</Row>
|
|
</xsl:when>
|
|
</xsl:choose>
|
|
</xsl:template>
|
|
</xsl:stylesheet>`
|
|
|
|
const handleGenerateExcel = () => {
|
|
// Define the example XML data
|
|
const xmlData = `
|
|
<root>
|
|
<Kvp>
|
|
<style_id>1</style_id>
|
|
<region>Region 1</region>
|
|
<city>City 1</city>
|
|
<house_count>10</house_count>
|
|
<square>1000</square>
|
|
<people_count>500</people_count>
|
|
<volume_heat>200</volume_heat>
|
|
<sum_heat>1000</sum_heat>
|
|
<volume_hwater>300</volume_hwater>
|
|
<sum_hwater>1500</sum_hwater>
|
|
<volume_cwater>400</volume_cwater>
|
|
<sum_cwater>2000</sum_cwater>
|
|
<volume_sewers>500</volume_sewers>
|
|
<sum_sewers>2500</sum_sewers>
|
|
<saldo_out>300</saldo_out>
|
|
</Kvp>
|
|
</root>
|
|
`
|
|
|
|
// Parse the XSL template and XML data
|
|
const parser = new DOMParser()
|
|
const xslDoc = parser.parseFromString(xslTemplate, "application/xml")
|
|
const xmlDoc = parser.parseFromString(xmlData, "application/xml")
|
|
|
|
// Apply the transformation
|
|
const xsltProcessor = new XSLTProcessor()
|
|
xsltProcessor.importStylesheet(xslDoc)
|
|
const resultDocument = xsltProcessor.transformToDocument(xmlDoc)
|
|
|
|
// Serialize the result to a string
|
|
const serializer = new XMLSerializer()
|
|
const resultXml = serializer.serializeToString(resultDocument)
|
|
|
|
// Add missing Excel-specific headers if needed
|
|
const correctedXml = `<?xml version="1.0" encoding="utf-8"?>\n` + resultXml
|
|
|
|
// Convert to Blob and trigger download
|
|
const blob = new Blob([correctedXml], { type: "application/vnd.ms-excel" })
|
|
const url = URL.createObjectURL(blob)
|
|
const link = document.createElement("a")
|
|
link.href = url
|
|
link.download = "template.xls"
|
|
link.click()
|
|
|
|
URL.revokeObjectURL(url)
|
|
}
|
|
|
|
const TemplateFormET = ({
|
|
templateUrl
|
|
}: {
|
|
templateUrl: string
|
|
}) => {
|
|
const [templateUint8Array, setTemplateUint8Array] = useState<Uint8Array | null>(null)
|
|
const [loading, setLoading] = useState(false)
|
|
|
|
const loadTemplate = async (templateUrl: string) => {
|
|
setLoading(true)
|
|
try {
|
|
const response = await fetch(templateUrl)
|
|
const templateArrayBuffer = await response.arrayBuffer()
|
|
|
|
setTemplateUint8Array(new Uint8Array(templateArrayBuffer))
|
|
} catch (error) {
|
|
console.error("Error generating DOCX:", error)
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}
|
|
|
|
const loadTags = async (templateUint8Array: Uint8Array) => {
|
|
const handler = new TemplateHandler()
|
|
const tags = await handler.parseTags(templateUint8Array)
|
|
|
|
console.log(tags)
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (templateUint8Array) {
|
|
loadTags(templateUint8Array)
|
|
}
|
|
}, [templateUint8Array])
|
|
|
|
useEffect(() => {
|
|
if (templateUrl) {
|
|
loadTemplate(templateUrl)
|
|
}
|
|
}, [templateUrl])
|
|
|
|
return (
|
|
<div>
|
|
|
|
</div>
|
|
)
|
|
}
|
|
|
|
interface TemplateCommand extends CommandSummary {
|
|
children?: CommandSummary[]
|
|
}
|
|
|
|
export function parseCommandList(commands: CommandSummary[]): TemplateCommand[] {
|
|
function parseBlock(startIndex: number, currentElement?: string): [TemplateCommand[], number] {
|
|
const block: TemplateCommand[] = []
|
|
let i = startIndex
|
|
|
|
while (i < commands.length) {
|
|
const command = commands[i]
|
|
|
|
if (command.type === "FOR") {
|
|
const [elementName, , arrayName] = command.code.split(" ")
|
|
const forCommand: TemplateCommand = {
|
|
raw: command.raw,
|
|
type: command.type,
|
|
code: arrayName,
|
|
children: [],
|
|
}
|
|
|
|
const [children, nextIndex] = parseBlock(i + 1, elementName)
|
|
forCommand.children = children
|
|
i = nextIndex
|
|
block.push(forCommand)
|
|
} else if (command.type === "END-FOR") {
|
|
return [block, i + 1]
|
|
} else {
|
|
let code = command.code
|
|
if (currentElement && (code.startsWith(`${currentElement}.`) || code.startsWith(`$${currentElement}.`))) {
|
|
code = code.replace(`$${currentElement}.`, "").replace(`${currentElement}.`, "")
|
|
}
|
|
|
|
block.push({
|
|
...command,
|
|
code,
|
|
})
|
|
i++
|
|
}
|
|
}
|
|
|
|
return [block, i]
|
|
}
|
|
|
|
const [parsed] = parseBlock(0)
|
|
return parsed
|
|
}
|
|
|
|
const FormLoop = ({
|
|
control,
|
|
register,
|
|
command,
|
|
}: {
|
|
control: Control<FieldValues, any>,
|
|
register: UseFormRegister<FieldValues>,
|
|
command: TemplateCommand,
|
|
}) => {
|
|
const { fields, append, remove } = useFieldArray({
|
|
name: command.code,
|
|
control
|
|
})
|
|
|
|
return (
|
|
<Stack align="center">
|
|
<Stack w='100%' key={command.code}>
|
|
{
|
|
fields.map((field, index) => (
|
|
<Flex w='100%' justify='space-between' align='flex-end' key={field.id}>
|
|
{command.children &&
|
|
command.children.map(c =>
|
|
renderCommand(
|
|
control,
|
|
register,
|
|
c,
|
|
`${c.code}`,
|
|
`${command.code}.${index}.${c.code}`,
|
|
`${command.code}.${index}.${c.code}`
|
|
)
|
|
)}
|
|
<Button variant='subtle' onClick={() => {
|
|
remove(index)
|
|
}}>
|
|
<IconX />
|
|
</Button>
|
|
</Flex>
|
|
))
|
|
}
|
|
</Stack>
|
|
<ActionIcon onClick={() => {
|
|
if (command.children) {
|
|
append(command.children.map(c => c.code).reduce((acc, key) => {
|
|
acc[key] = '';
|
|
return acc;
|
|
}, {} as Record<string, string>))
|
|
}
|
|
}}>
|
|
<IconPlus />
|
|
</ActionIcon>
|
|
</Stack>
|
|
)
|
|
}
|
|
|
|
const renderCommand = (
|
|
control: Control<FieldValues, any>,
|
|
register: UseFormRegister<FieldValues>,
|
|
command: CommandSummary,
|
|
label: string,
|
|
key: string,
|
|
name: string,
|
|
) => {
|
|
if (command.type === 'INS') {
|
|
return (
|
|
<TextInput
|
|
label={label}
|
|
key={key}
|
|
{...register(name)}
|
|
/>
|
|
)
|
|
}
|
|
|
|
if (command.type === 'IMAGE') {
|
|
return (
|
|
<Controller
|
|
key={key}
|
|
name={name}
|
|
control={control}
|
|
render={({ field: { onChange, value } }) => (
|
|
<Dropzone
|
|
accept={IMAGE_MIME_TYPE}
|
|
maxSize={5 * 1024 ** 2}
|
|
onReject={(files) => console.log('rejected files', files)}
|
|
onDrop={(files) => {
|
|
console.log(files[0])
|
|
files[0].arrayBuffer().then(res => {
|
|
onChange({
|
|
width: 6,
|
|
height: 6,
|
|
data: new Uint8Array(res),
|
|
extension: files[0]?.path?.match(/\.[^.]+$/)?.[0] || ""
|
|
})
|
|
})
|
|
}}
|
|
maxFiles={1}
|
|
>
|
|
<Group justify="center" gap="xl" mih={220} style={{ pointerEvents: 'none' }}>
|
|
<Dropzone.Accept>
|
|
<IconUpload size={52} color="var(--mantine-color-blue-6)" stroke={1.5} />
|
|
</Dropzone.Accept>
|
|
<Dropzone.Reject>
|
|
<IconX size={52} color="var(--mantine-color-red-6)" stroke={1.5} />
|
|
</Dropzone.Reject>
|
|
<Dropzone.Idle>
|
|
<IconFileTypeDocx size={52} color="var(--mantine-color-dimmed)" stroke={1.5} />
|
|
</Dropzone.Idle>
|
|
|
|
<div>
|
|
<Text size="xl" inline>
|
|
Drag files here or click to select files
|
|
</Text>
|
|
<Text size="sm" c="dimmed" inline mt={7}>
|
|
Attach as many files as you like, each file should not exceed 5mb
|
|
</Text>
|
|
</div>
|
|
</Group>
|
|
</Dropzone>
|
|
)}
|
|
/>
|
|
)
|
|
}
|
|
}
|
|
|
|
const TemplateForm = ({
|
|
templateUrl,
|
|
}: {
|
|
templateUrl: string,
|
|
}) => {
|
|
const { register, control, handleSubmit, reset, watch, formState } = useForm({
|
|
mode: 'onChange',
|
|
})
|
|
|
|
const [loading, setLoading] = useState(false)
|
|
const [saving, setSaving] = useState(false)
|
|
|
|
const [templateUint8Array, setTemplateUint8Array] = useState<Uint8Array | null>(null)
|
|
|
|
const [commandList, setCommandList] = useState<TemplateCommand[]>([])
|
|
|
|
const saveTest = async (templateUint8Array: Uint8Array, data: any) => {
|
|
setSaving(true)
|
|
|
|
try {
|
|
// Generate the DOCX file with the replacement
|
|
const report = await createReport({
|
|
template: templateUint8Array, // Ensure it's Uint8Array
|
|
data: data,
|
|
})
|
|
|
|
// Convert Uint8Array to a Blob
|
|
const blob = new Blob([report], {
|
|
type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
})
|
|
|
|
// Create a download link and trigger the download
|
|
const url = URL.createObjectURL(blob)
|
|
const a = document.createElement("a")
|
|
a.href = url
|
|
a.download = "report.docx"
|
|
document.body.appendChild(a)
|
|
a.click()
|
|
document.body.removeChild(a)
|
|
|
|
URL.revokeObjectURL(url)
|
|
} catch (error) {
|
|
console.error("Error generating DOCX:", error)
|
|
} finally {
|
|
setSaving(false)
|
|
}
|
|
}
|
|
|
|
const loadTemplate = async () => {
|
|
setLoading(true)
|
|
|
|
try {
|
|
const response = await fetch(templateUrl)
|
|
const templateArrayBuffer = await response.arrayBuffer()
|
|
|
|
setTemplateUint8Array(new Uint8Array(templateArrayBuffer))
|
|
} catch (error) {
|
|
console.error("Error generating DOCX:", error)
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}
|
|
|
|
const loadCommands = async (templateUint8Array: Uint8Array) => {
|
|
try {
|
|
await listCommands(templateUint8Array).then(l => {
|
|
setCommandList(parseCommandList(l))
|
|
})
|
|
} catch (error) {
|
|
console.error("Error loading commands from DOCX:", error)
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (templateUint8Array) {
|
|
loadCommands(templateUint8Array)
|
|
}
|
|
}, [templateUint8Array])
|
|
|
|
const onSubmit: SubmitHandler<any> = async (data) => {
|
|
try {
|
|
if (templateUint8Array && data) {
|
|
saveTest(templateUint8Array, data)
|
|
}
|
|
} catch (error) {
|
|
console.error(error)
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (templateUrl) {
|
|
loadTemplate()
|
|
}
|
|
}, [templateUrl])
|
|
|
|
if (commandList) {
|
|
return (
|
|
<form onSubmit={handleSubmit(onSubmit)}>
|
|
<Stack>
|
|
{commandList.map(command => {
|
|
if (command.type === 'FOR') {
|
|
return (
|
|
<FormLoop key={command.code} control={control} register={register} command={command} />
|
|
)
|
|
} else {
|
|
return renderCommand(control, register, command, command.code, command.code, command.code)
|
|
}
|
|
})}
|
|
<Button type='submit'>Submit</Button>
|
|
</Stack>
|
|
</form>
|
|
)
|
|
}
|
|
}
|
|
|
|
const PrintReport = () => {
|
|
const [loading, setLoading] = useState(false)
|
|
|
|
return (
|
|
<Stack p='sm' gap='sm' w='100%'>
|
|
<TemplateForm templateUrl="/template_table.docx" />
|
|
|
|
<Flex gap='sm'>
|
|
<Button onClick={handleGenerateExcel}>Сохранить в Excel</Button>
|
|
</Flex>
|
|
</Stack>
|
|
)
|
|
}
|
|
|
|
export default PrintReport
|