skip to Main Content

I need to create a website (also local one is fine) that reads an excel file and shows the content into a table and update the contents periodically.

I have already written something but it doesn’t update the content of the website periodically as it should.
Can you help me?

This is how the page select and read the file:

document.getElementById('file-input').addEventListener('change', function (event) {
    const file = event.target.files[0];
    if (file) {
        lastModified = new Date(file.lastModified);
        const reader = new FileReader();
        reader.onload = function (e) {
            fileData = new Uint8Array(e.target.result);
            updateTable();
        };
        reader.readAsArrayBuffer(file);
    }
});

function updateTable() {
    if (fileData) {
        const workbook = XLSX.read(fileData, { type: 'array' });
        const firstSheetName = workbook.SheetNames[0];
        const worksheet = workbook.Sheets[firstSheetName];
        const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });

        const tableBody = document.getElementById('excel-data');
        tableBody.innerHTML = '';

        jsonData.forEach((row, rowIndex) => {
            if (rowIndex === 0) return; // Skip header row
            const tr = document.createElement('tr');
            row.forEach(cell => {
                const td = document.createElement('td');
                td.className = 'py-2 px-4 border-b border-gray-200';
                td.textContent = cell;
                tr.appendChild(td);
            });
            tableBody.appendChild(tr);
        });

        document.getElementById('last-modified')
          .textContent = `Data ultima modifica del file Excel: ${lastModified.toLocaleString()}`;
    }
}

this is how it should get updated every 5 minutes:

setInterval(() => {
    if (fileData) {
        updateTable();
    }
}, 300000);

Using the the debugger the function updateTable() seems to be called and get redirected to the following tailwind function

new MutationObserver(async r => {
        let e = !1;
        if (!cf) {
            cf = new MutationObserver(async () => await pf(!0));
            for (let t of document.querySelectorAll(`style[type="${uf}"]`))
                Pv(t)
        }
        for (let t of r)
            for (let i of t.addedNodes)
                i.nodeType === 1 && i.tagName === "STYLE" && i.getAttribute("type") === uf && (Pv(i),
                e = !0);
        await pf(e)
    }

but after this no contents gets updated although the excel file got modified in the meanwhile.

2

Answers


  1. This fundamentally can’t work as an automated process, in the way you’ve designed it.

    1. Bear in mind that your code only reads data into fileData when the "change" event occurs in the file input box. This means you need to manually go into that input and select a file again, before it will read any new data. And the "change" event will only occur if you select a different file. Opening up the dialog and selecting the same one again won’t trigger the event.

    2. Even if you change the code so that your interval code selects the file currently in the input control, and sends it to the FileReader again, it will not trigger the reader’s onload function. There is no new data to be read anyway – the file is only taken from the disk again when the user selects a file in the input control.

    This is a browser security restriction which you cannot work around. Imagine the danger / damage which could be caused if browser code could arbitrarily read data from a user’s disk whenever it wanted to.

    Instead it can only read such data when a user, through the UI, has specifically provided a file that the user is happy for the browser to see, and it will only work on the version of the file that the user explicitly provided. The user did not give permission for some later version of the file to be accessed by the browser whenever it wants to.

    If you want this to work and be fully automated you will need to store the Excel file on your webserver instead, and fetch it from there.

    Login or Signup to reply.
  2. To periodically update and display data from an Excel file on a website, you’ll need to serve the file from a backend and fetch updates via AJAX or WebSocket. This approach overcomes the limitation of local file handling in browsers. Here’s how you can implement it step-by-step:

    1. Backend Setup
      Use a server-side language or framework (e.g., Node.js, Python, PHP) to host the Excel file and read its content dynamically.

    Example with Node.js:
    Install necessary libraries:

    bash

    npm install express multer xlsx
    

    Create a basic server:

    const express = require('express');
    const multer = require('multer');
    const xlsx = require('xlsx');
    const app = express();
    
    const upload = multer({ dest: 'uploads/' }); // Temporary file storage
    
    app.use(express.static('public')); // Serve HTML and JS
    
    // Endpoint to fetch Excel data
    app.get('/data', (req, res) => {
        const workbook = xlsx.readFile('uploads/data.xlsx'); // Path to your Excel file
        const sheetName = workbook.SheetNames[0]; // Read the first sheet
        const data = xlsx.utils.sheet_to_json(workbook.Sheets[sheetName]);
        res.json(data); // Send JSON to the client
    });
    
    // Upload a new Excel file (optional for dynamic updates)
    app.post('/upload', upload.single('file'), (req, res) => {
        res.send('File uploaded');
    });
    
    app.listen(3000, () => console.log('Server running on http://localhost:3000'));
    
    1. Frontend Setup
      Create an HTML file that periodically fetches the Excel data:

      Excel Data Viewer

      Excel Data

       <script>
           async function fetchExcelData() {
               try {
                   const response = await fetch('/data');
                   const data = await response.json();
      
                   // Clear existing table
                   document.getElementById('tableHead').innerHTML = '';
                   document.getElementById('tableBody').innerHTML = '';
      
                   // Populate table header
                   if (data.length > 0) {
                       const headers = Object.keys(data[0]);
                       headers.forEach(header => {
                           const th = document.createElement('th');
                           th.textContent = header;
                           document.getElementById('tableHead').appendChild(th);
                       });
                   }
      
                   // Populate table body
                   data.forEach(row => {
                       const tr = document.createElement('tr');
                       Object.values(row).forEach(cell => {
                           const td = document.createElement('td');
                           td.textContent = cell;
                           tr.appendChild(td);
                       });
                       document.getElementById('tableBody').appendChild(tr);
                   });
               } catch (error) {
                   console.error('Error fetching data:', error);
               }
           }
      
           // Fetch data every 5 seconds
           setInterval(fetchExcelData, 5000);
           fetchExcelData();
       </script>
      
    2. Usage
      Place your Excel file at uploads/data.xlsx on the server.
      Start the server: node server.js.
      Open the frontend in your browser: http://localhost:3000.
      The table will refresh every 5 seconds with the latest data from the Excel file.
      Benefits of This Approach:
      Scalable: Works for multiple users without requiring local file selection.
      Automated Updates: Fetches the latest data without manual intervention.
      Secure: Limits file access to the server.
      If you want real-time updates, you can replace setInterval with WebSocket to push updates as the Excel file changes.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search