Un tableau
This commit is contained in:
parent
d011746d55
commit
f27349dcf9
@ -39,7 +39,7 @@ export default {
|
||||
|
||||
// If we're building for production (npm run build
|
||||
// instead of npm run dev), minify
|
||||
production && terser()
|
||||
//production && terser()
|
||||
],
|
||||
watch: {
|
||||
clearScreen: false
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import getTableRawContentFromFile from './getTableRawContentFromFile.js'
|
||||
import {getTableRawContentFromFile, tableRawContentToObjects} from './getTableRawContentFromFile.js'
|
||||
|
||||
const ODS_TYPE = "application/vnd.oasis.opendocument.spreadsheet";
|
||||
const XLSX_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
@ -12,27 +12,60 @@
|
||||
$: file = files && files[0]
|
||||
$: console.log('file', file)
|
||||
$: tableRawContent = file && getTableRawContentFromFile(file)
|
||||
$: console.log('tableRawContent', tableRawContent)
|
||||
$: tableObjectSheets = tableRawContent && tableRawContent.then(tableRawContentToObjects) || []
|
||||
|
||||
</script>
|
||||
|
||||
<h1>Import fichier .ods et .xslx</h1>
|
||||
|
||||
<section>
|
||||
<h2>Import</h2>
|
||||
<label>
|
||||
Fichier à importer:
|
||||
<input bind:files type="file" id="file-input" accept="{ ['.ods', '.xlsx', ODS_TYPE, XLSX_TYPE].join(',') }" />
|
||||
</label>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Résultat</h2>
|
||||
{#await tableObjectSheets}
|
||||
(fichier en cours d'analyse)
|
||||
{:then tableObjectSheets}
|
||||
{#each [...tableObjectSheets] as [sheetName, data]}
|
||||
<details>
|
||||
<summary>{sheetName} ({data.length} lignes)</summary>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
{#each Object.keys(data[0]) as column}
|
||||
<th>{column}</th>
|
||||
{/each}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each data as row}
|
||||
<tr>
|
||||
{#each Object.keys(data[0]) as column}
|
||||
<td><div class="cell-content">{row[column]}</div></td>
|
||||
{/each}
|
||||
</tr>
|
||||
{/each}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</details>
|
||||
{/each}
|
||||
{/await}
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
:global(main) {
|
||||
text-align: center;
|
||||
padding: 1em;
|
||||
max-width: 240px;
|
||||
max-width: 80rem;
|
||||
margin: 0 auto;
|
||||
|
||||
@media (min-width: 640px) {
|
||||
@ -40,4 +73,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
table{
|
||||
thead{
|
||||
tr{
|
||||
background: #EEE;
|
||||
}
|
||||
}
|
||||
|
||||
tr{
|
||||
border-bottom: 1px solid #CCC;
|
||||
}
|
||||
|
||||
td, th{
|
||||
vertical-align: top;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
td{
|
||||
.cell-content{
|
||||
max-height: 6rem;
|
||||
max-width: 16rem;
|
||||
overflow: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@ -2,7 +2,5 @@ import App from './App.svelte';
|
||||
|
||||
const app = new App({
|
||||
target: document.querySelector('.svelte-main'),
|
||||
props: {
|
||||
name: 'from Svelte'
|
||||
}
|
||||
props: {}
|
||||
});
|
||||
|
||||
@ -15,7 +15,7 @@ function parseXML(str){
|
||||
|
||||
/**
|
||||
* @typedef TableCellRawContent
|
||||
* @prop {string} value
|
||||
* @prop {string | null | undefined} value
|
||||
* @prop {'float' | 'percentage' | 'currency' | 'date' | 'time' | 'boolean' | 'string' | 'b' | 'd' | 'e' | 'inlineStr' | 'n' | 's' | 'str'} type
|
||||
*
|
||||
*/
|
||||
@ -24,39 +24,6 @@ const ODS_TYPE = "application/vnd.oasis.opendocument.spreadsheet";
|
||||
const XLSX_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||
|
||||
|
||||
/**
|
||||
* Converts a cell value to the appropriate JavaScript type based on its cell type.
|
||||
* @param {string} value - The value of the cell.
|
||||
* @param {TableCellRawContent['type']} cellType - The type of the cell.
|
||||
* @returns {any} The converted value.
|
||||
*/
|
||||
function convertCellValue(value, cellType) {
|
||||
if(value === ''){
|
||||
return ''
|
||||
}
|
||||
|
||||
switch (cellType) {
|
||||
case 'float':
|
||||
case 'percentage':
|
||||
case 'currency':
|
||||
case 'n': // number
|
||||
return parseFloat(value);
|
||||
case 'date':
|
||||
case 'd': // date
|
||||
return new Date(value);
|
||||
case 'boolean':
|
||||
case 'b': // boolean
|
||||
return value === '1' || value === 'true';
|
||||
case 's': // shared string
|
||||
case 'inlineStr': // inline string
|
||||
case 'string':
|
||||
case 'e': // error
|
||||
case 'time':
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts raw table content from an ODS file.
|
||||
* @param {File} file - The ODS file.
|
||||
@ -66,7 +33,6 @@ function convertCellValue(value, cellType) {
|
||||
*/
|
||||
async function getTableRawContentFromODSFile(file, unzip, parseXML) {
|
||||
const zip = await unzip(file);
|
||||
console.log('zip', zip)
|
||||
const entries = zip.entries;
|
||||
|
||||
// Extract the content.xml file which contains the spreadsheet data
|
||||
@ -179,7 +145,7 @@ async function getTableRawContentFromXSLXFile(file, unzip, parseXML) {
|
||||
* @param {File} file
|
||||
* @returns {Promise<Map<SheetName, TableCellRawContent[][]>>}
|
||||
*/
|
||||
export default function getTableRawContentFromFile(file){
|
||||
export function getTableRawContentFromFile(file){
|
||||
if(file.type === ODS_TYPE)
|
||||
return getTableRawContentFromODSFile(file, unzip, parseXML)
|
||||
|
||||
@ -190,3 +156,78 @@ export default function getTableRawContentFromFile(file){
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Converts a cell value to the appropriate JavaScript type based on its cell type.
|
||||
* @param {TableCellRawContent} _
|
||||
* @returns {number | boolean | string | Date} The converted value.
|
||||
*/
|
||||
function convertCellValue({value, type}) {
|
||||
if(value === ''){
|
||||
return ''
|
||||
}
|
||||
if(value === null || value === undefined){
|
||||
return ''
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 'float':
|
||||
case 'percentage':
|
||||
case 'currency':
|
||||
case 'n': // number
|
||||
return parseFloat(value);
|
||||
case 'date':
|
||||
case 'd': // date
|
||||
return new Date(value);
|
||||
case 'boolean':
|
||||
case 'b': // boolean
|
||||
return value === '1' || value === 'true';
|
||||
case 's': // shared string
|
||||
case 'inlineStr': // inline string
|
||||
case 'string':
|
||||
case 'e': // error
|
||||
case 'time':
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {TableCellRawContent[][]} rawContent
|
||||
* @returns {any[]}
|
||||
*/
|
||||
function rawContentToObjects(rawContent){
|
||||
let [firstRow, ...dataRows] = rawContent
|
||||
|
||||
/** @type {string[]} */
|
||||
//@ts-expect-error trust me, this is true after the filter
|
||||
const columns = firstRow.filter(({value}) => typeof value === 'string' && value.length >= 1).map(r => r.value)
|
||||
|
||||
return dataRows.map(row => {
|
||||
const obj = Object.create(null)
|
||||
let empty = true
|
||||
columns.forEach((column, i) => {
|
||||
const rawValue = row[i]
|
||||
obj[column] = rawValue ? convertCellValue(rawValue) : ''
|
||||
empty = empty && (obj[column] === '')
|
||||
})
|
||||
return empty ? undefined : obj
|
||||
}).filter(x => x !== undefined) // remove empty rows
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Map<SheetName, TableCellRawContent[][]>} rawContentSheets
|
||||
* @returns {Map<SheetName, any[]>}
|
||||
*/
|
||||
export function tableRawContentToObjects(rawContentSheets){
|
||||
return new Map(
|
||||
[...rawContentSheets].map(([sheetName, rawContent]) => {
|
||||
return [sheetName, rawContentToObjects(rawContent)]
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user