jmaister / excellentexport

Javascript export to Excel
MIT License
1.36k stars 305 forks source link

Invalid file loaded via mobile view [Vuetify - DataTable] #367

Closed AlexKutko closed 3 years ago

AlexKutko commented 3 years ago

Hello everyone, I have a question.

I am using Vuetify in my project. Using the Data-Table component, I can adapt the table to my mobile phone. If you download the file using your computer. Excel file is correct

However, when downloading a file in mobile view. The following happens (picture 1) image picture 1 - The downloaded Excel file in the mobile view of the site [INVALID]

The correct file looks like this (picture 2) image picture 2 - The downloaded Excel file in the desktop view of the site [VALID]

Data-table code:

<v-data-table
     class="dataTable"
     hide-default-footer
     disable-pagination
     :search="search"
     :headers="headers"
     :items="filteredTransaction"
     style="margin-bottom:50px;"
     :items-per-page="0">
</v-data-table>

Download Action code:


<template v-slot:item="{item }">
    <a  class="v-btn__content px-auto" download="TransactionReport.xls"
onclick="try {return ExcellentExport.excel(this, 'data_table', 'Транзакционный отчет');} catch{alert('Невозможно скачать пустой отчет.')}">
{{item.text}}
</a>
</template>```
jmaister commented 3 years ago

It looks like the mobile version has a different HTML layout than the desktop version. Could you share the HTML page of each version to test it ?

AlexKutko commented 3 years ago
<template>
<div style="height:100%;">
    <v-card class="fill-height print" height="100%">
    <v-toolbar
      flat
      height="auto"
      class="elevation-5"
      id="reportCard"
    >
    <v-row>
        <v-col sm="12" md="6" lg="6" xl="6" cols="12" xs="12">
            <v-toolbar-title style="white-space: pre-wrap; word-wrap: break-word;" id="reportHeader">
                <h4>Транзакционный отчет</h4>
                <h6 class="text--disabled no-print">Представляет транзакции за указанный период</h6>
                <h6 class="text--disabled" v-if="startDate && endDate">Период: {{startDate}} - {{endDate}}</h6>
                <h6 class="text--disabled" id="currentSystemCaption" v-if="currentSystem">Система ТК: {{currentSystem}}</h6>

            </v-toolbar-title>
        </v-col>
        <v-spacer/>
        <v-spacer/>
        <v-col class="no-print d-flex flex-row-reverse" sm="12" md="2" lg="2" xl="2" cols="12">
          <DateIntervalForm
            buttonText="Создать"
            buttonIcon="mdi-play"
            v-on:onValidate="CreateReport"
            :isActive="loading"/>
        </v-col>
        <v-col class="no-print d-flex flex-row-reverse" sm="12" md="2" lg="2" xl="2" cols="12">
            <v-container id="dropdown-action" class="ma-0 pa-0" >
              <v-overflow-btn
                ref="action_lookup"
                dark
                v-model="selectedAction"
                x-large
                color="primary "
                background-color="primary"
                class="elevation-1 primary pl-1  "
                :items="exportButtonActions"
                :value="exportButtonActions[0]"
                segmented
                :prepend-icon="actionIcon"
                hide-details=""
                target="#dropdown-action"
                id="action_lookup"
                v-bind:disabled="loading || reportData.length === 0"
              >
              <template v-slot:item="{item }">
                                  <a  v-if="item.text === 'Печать'" class="v-btn__content px-auto" @click="selected = true"  onclick="window.print()">{{item.text}}</a>
                  <a  v-else class="v-btn__content px-auto" @click="selected = true" :download="'TransactionReport_' + new Date().toLocaleDateString('ru-RU', {year:'numeric', month:'2-digit', day:'2-digit', hour:'2-digit', minute:'2-digit'}) + '.xls'"
                    onclick="try {return ExcellentExport.excel(this, 'data_table', 'Транзакционный отчет');} catch{alert('Невозможно скачать пустой отчет.')}">
                    {{item.text}}
                  </a>

              </template>
              <template v-slot:selection="{item, selected}">
                  <a  v-if="item.text === 'Печать'" class="v-btn__content" @click="selected = true"  onclick="window.print()">{{item.text}}</a>
                  <a  v-else class="v-btn__content" @click="selected = true" :download="'TransactionReport_' + new Date().toLocaleDateString('ru-RU', {year:'numeric', month:'2-digit', day:'2-digit', hour:'2-digit', minute:'2-digit'}) + '.xls'"
                    onclick="try {return ExcellentExport.excel(this, 'data_table', 'Транзакционный отчет');} catch{alert('Невозможно скачать пустой отчет.')}">
                    {{item.text}}
                  </a>
              </template>
              </v-overflow-btn>
            </v-container>
        </v-col>
    </v-row>
    </v-toolbar>
    <v-card-title>
      <v-row>
        <v-col>
          <v-text-field
            v-model="search"
            append-icon="mdi-magnify"
            label="Поиск.."
            class="no-print"
            v-bind:disabled="loading"
          ></v-text-field>
        </v-col>
        <v-col>
          <v-select multiple  clearable v-bind:disabled="loading"  label="Выбор карт" class="no-print"  :items="columnValueList('cardNumber')" v-model="filters.cardNumber">
            <template v-slot:prepend-item>
              <v-list-item
                @click="toggleAll"
              >
              <v-list-item-action>
                <v-icon >
                  {{ icon }}
                </v-icon>
              </v-list-item-action>
                <v-list-item-content>
                  <v-list-item-title>
                    {{selectAllText}}
                  </v-list-item-title>
                </v-list-item-content>
              </v-list-item>
              <v-divider class="mt-2"></v-divider>
            </template>
            <template v-slot:selection="{ item, index }">
              <v-chip small color="primary" v-if="index < 2">
                <span>{{ item }}</span>
              </v-chip>
              <span
                v-if="index === 1"
                class="text--disabled"
              >
                ( +{{ Array.from(new Set(filters.cardNumber)).length - 2 }} других  )
              </span>
            </template>
          </v-select>
        </v-col>
      </v-row>
    </v-card-title>
    <v-card-text style="padding:0px;">
       <v-skeleton-loader
            v-if="loading"
            style="height:100%"
            type="table"
            tile
            class="no-print"
          >
          </v-skeleton-loader>
        <div v-else class="fill-height">
          <v-data-table
            class="dataTable"
            hide-default-footer
            disable-pagination
            :search="search"
            :headers="headers"
            :items="filteredTransaction"
            style="margin-bottom:50px;"
            :items-per-page="0"
            sort-by="transactionDateTime"
            :sort-desc="false"
          >
          <template slot="body.append">
            <tr class="data-table-footer">
                <th class="text-subtitle-1 font-weight-black" colspan="0">Итого:</th>
                <th class="text-subtitle-1 font-weight-black" colspan="0">&Sigma; {{filteredTransaction.length}}</th>
                <th class="text-subtitle-1 font-weight-black empty-field" colspan="0"></th>
                <th class="text-subtitle-1 font-weight-black empty-field" colspan="0"></th>
                <th class="text-subtitle-1 font-weight-black">{{ sumField('value').toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, '$& ') }} л.</th>
                <th class="text-subtitle-1 font-weight-black pr-0">{{ sumField('sum').toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, '$& ') }} руб.</th>
            </tr>
          </template>
         <template v-slot:group.header="{items, isOpen, toggle}">
            <th colspan="6" class="group_header">
              <v-icon @click="toggle"
                >{{ isOpen ? 'mdi-minus' : 'mdi-plus' }}
              </v-icon>
              Номер карты: {{ items[0].cardNumber }}
            </th>
          </template>
          <template v-slot:item.transactionDateTime="{ item }">
            {{new Date(item.transactionDateTime).toLocaleDateString('ru-RU', {month:'short', day:'numeric', year:'2-digit', hour:'2-digit', minute:'2-digit'})}}
          </template>
          </v-data-table>
        </div>
    </v-card-text>
    </v-card>

</div>
</template>
jmaister commented 3 years ago

I mean the HTML generated in the browser. Looks like the mobile version generates a different TABLE tag.

You could try to use an array to load the data instead of the HTML table.

AlexKutko commented 3 years ago

PC version in the browser

<table id="data_table">
   <colgroup>
      <col class="">
      <col class="">
      <col class="">
      <col class="">
      <col class="">
      <col class="">
   </colgroup>
   <thead class="v-data-table-header">
      <tr>
         <th role="columnheader" scope="col" aria-label="Дата/Время: Упорядочено по возрастанию. Активируйте для упорядочивания убыванию." aria-sort="ascending" class="text-start sortable active asc"><span>Дата/Время</span><i aria-hidden="true" class="v-icon notranslate v-data-table-header__icon mdi mdi-arrow-up theme--light" style="font-size: 18px;"></i></th>
         <th role="columnheader" scope="col" aria-label="Бренд АЗС" class="text-start"><span>Бренд АЗС</span></th>
         <th role="columnheader" scope="col" aria-label="Номер карты: Не упорядочено. Активируйте для упорядочивания по возрастанию." aria-sort="none" class="text-start sortable"><span>Номер карты</span><i aria-hidden="true" class="v-icon notranslate v-data-table-header__icon mdi mdi-arrow-up theme--light" style="font-size: 18px;"></i></th>
         <th role="columnheader" scope="col" aria-label="Марка топлива: Не упорядочено. Активируйте для упорядочивания по возрастанию." aria-sort="none" class="text-start sortable"><span>Марка топлива</span><i aria-hidden="true" class="v-icon notranslate v-data-table-header__icon mdi mdi-arrow-up theme--light" style="font-size: 18px;"></i></th>
         <th role="columnheader" scope="col" aria-label="Заправлено: Не упорядочено. Активируйте для упорядочивания по возрастанию." aria-sort="none" class="text-start sortable"><span>Заправлено</span><i aria-hidden="true" class="v-icon notranslate v-data-table-header__icon mdi mdi-arrow-up theme--light" style="font-size: 18px;"></i></th>
         <th role="columnheader" scope="col" aria-label="Сумма (руб.): Не упорядочено. Активируйте для упорядочивания по возрастанию." aria-sort="none" class="text-start sortable"><span>Сумма (руб.)</span><i aria-hidden="true" class="v-icon notranslate v-data-table-header__icon mdi mdi-arrow-up theme--light" style="font-size: 18px;"></i></th>
      </tr>
   </thead>
   <tbody>
      <tr class="">
         <td class="text-start"> 1 дек. 20 г., 18:26 </td>
         <td class="text-start">Лукойл</td>
         <td class="text-start">3005633851</td>
         <td class="text-start">АИ-95</td>
         <td class="text-start">25</td>
         <td class="text-start">1144.61</td>
      </tr>
      <tr class="">
         <td class="text-start"> 22 дек. 20 г., 07:08 </td>
         <td class="text-start">ЛУКОЙЛ</td>
         <td class="text-start">3005633851</td>
         <td class="text-start">АИ-92</td>
         <td class="text-start">20</td>
         <td class="text-start">832.08</td>
      </tr>
      <tr class="">
         <td class="text-start"> 22 дек. 20 г., 19:25 </td>
         <td class="text-start">ЛУКОЙЛ</td>
         <td class="text-start">3005633851</td>
         <td class="text-start">АИ-92</td>
         <td class="text-start">15</td>
         <td class="text-start">624.06</td>
      </tr>
      <tr class="data-table-footer">
         <th colspan="0" class="text-subtitle-1 font-weight-black">Итого:</th>
         <th colspan="0" class="text-subtitle-1 font-weight-black">Σ 3</th>
         <th colspan="0" class="text-subtitle-1 font-weight-black empty-field"></th>
         <th colspan="0" class="text-subtitle-1 font-weight-black empty-field"></th>
         <th class="text-subtitle-1 font-weight-black">60.00 л.</th>
         <th class="text-subtitle-1 font-weight-black pr-0">2 600.75 руб.</th>
      </tr>
   </tbody>
</table>

Mobile version in the browser

<table id="data_table">
   <colgroup>
      <col class="">
      <col class="">
      <col class="">
      <col class="">
      <col class="">
      <col class="">
   </colgroup>
   <thead class="v-data-table-header v-data-table-header-mobile">
      <tr>
         <th>
            <div class="v-data-table-header-mobile__wrapper">
               <div class="v-input v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-text-field v-text-field--is-booted v-select">
                  <div class="v-input__control">
                     <div role="button" aria-haspopup="listbox" aria-expanded="false" aria-owns="list-112" class="v-input__slot">
                        <div class="v-select__slot">
                           <label for="input-112" class="v-label v-label--active theme--light" style="left: 0px; right: auto; position: absolute;">Сортировать по</label>
                           <div class="v-select__selections">
                              <span class="sortable v-chip v-chip--clickable v-chip--no-color theme--light v-size--default">
                                 <span class="v-chip__content">
                                    Дата/Время
                                    <div class="v-chip__close sortable active asc"><i aria-hidden="true" class="v-icon notranslate v-data-table-header__icon mdi mdi-arrow-up theme--light" style="font-size: 18px;"></i></div>
                                 </span>
                              </span>
                              <input id="input-112" readonly="readonly" type="text" aria-readonly="false" autocomplete="off">
                           </div>
                           <div class="v-input__append-inner">
                              <div class="v-input__icon v-input__icon--append"><i aria-hidden="true" class="v-icon notranslate mdi mdi-menu-down theme--light"></i></div>
                           </div>
                           <input type="hidden" value="transactionDateTime">
                        </div>
                        <div class="v-menu">
                           <!---->
                        </div>
                     </div>
                  </div>
               </div>
            </div>
         </th>
      </tr>
   </thead>
   <tbody>
      <tr class="v-data-table__mobile-table-row">
         <td class="v-data-table__mobile-row">
            <div class="v-data-table__mobile-row__header">Дата/Время</div>
            <div class="v-data-table__mobile-row__cell"> 1 февр. 21 г., 16:52 </div>
         </td>
         <td class="v-data-table__mobile-row">
            <div class="v-data-table__mobile-row__header">Бренд АЗС</div>
            <div class="v-data-table__mobile-row__cell">Газпромнефть</div>
         </td>
         <td class="v-data-table__mobile-row">
            <div class="v-data-table__mobile-row__header">Номер карты</div>
            <div class="v-data-table__mobile-row__cell">3005571680</div>
         </td>
         <td class="v-data-table__mobile-row">
            <div class="v-data-table__mobile-row__header">Марка топлива</div>
            <div class="v-data-table__mobile-row__cell">АИ-92</div>
         </td>
         <td class="v-data-table__mobile-row">
            <div class="v-data-table__mobile-row__header">Заправлено</div>
            <div class="v-data-table__mobile-row__cell">20</div>
         </td>
         <td class="v-data-table__mobile-row">
            <div class="v-data-table__mobile-row__header">Сумма (руб.)</div>
            <div class="v-data-table__mobile-row__cell">846.35</div>
         </td>
      </tr>
      <tr class="v-data-table__mobile-table-row">
         <td class="v-data-table__mobile-row">
            <div class="v-data-table__mobile-row__header">Дата/Время</div>
            <div class="v-data-table__mobile-row__cell"> 2 февр. 21 г., 17:15 </div>
         </td>
         <td class="v-data-table__mobile-row">
            <div class="v-data-table__mobile-row__header">Бренд АЗС</div>
            <div class="v-data-table__mobile-row__cell">Газпромнефть</div>
         </td>
         <td class="v-data-table__mobile-row">
            <div class="v-data-table__mobile-row__header">Номер карты</div>
            <div class="v-data-table__mobile-row__cell">3005571680</div>
         </td>
         <td class="v-data-table__mobile-row">
            <div class="v-data-table__mobile-row__header">Марка топлива</div>
            <div class="v-data-table__mobile-row__cell">АИ-92</div>
         </td>
         <td class="v-data-table__mobile-row">
            <div class="v-data-table__mobile-row__header">Заправлено</div>
            <div class="v-data-table__mobile-row__cell">20</div>
         </td>
         <td class="v-data-table__mobile-row">
            <div class="v-data-table__mobile-row__header">Сумма (руб.)</div>
            <div class="v-data-table__mobile-row__cell">848.39</div>
         </td>
      </tr>
      <tr class="data-table-footer">
         <th colspan="0" class="text-subtitle-1 font-weight-black">Итого:</th>
         <th colspan="0" class="text-subtitle-1 font-weight-black">Σ 2</th>
         <th colspan="0" class="text-subtitle-1 font-weight-black empty-field"></th>
         <th colspan="0" class="text-subtitle-1 font-weight-black empty-field"></th>
         <th class="text-subtitle-1 font-weight-black">40.00 л.</th>
         <th class="text-subtitle-1 font-weight-black pr-0">1 694.74 руб.</th>
      </tr>
   </tbody>
</table>