Lacier
  • Alternance Lacier
    • Gestion des Canvas dans le Panier
    • Chatbot
      • Étapes pour intégrer la suggestion de produit
    • Monitoring
    • Compression Image Excel
    • Inventaire
    • Gravure Laser
    • Cleaner Module
    • Scripts JavaScript Indépendants
      • Croix pour fermer le widget d'avis
      • Section Instagram
      • Section Panier Commander
      • Chatbot
    • Notification de Retard de Commande
    • Gestion des Templates de Mails
    • Relance Devis
    • Image FIlter
    • Affichage des produits
    • Attribute Replacer
Powered by GitBook
On this page
  • Introduction
  • Application
  1. Alternance Lacier

Compression Image Excel

Introduction

Cette application a été développée pour répondre au besoin de compresser les images dans un fichier Excel. Elle permet aux utilisateurs de télécharger un fichier contenant des images de grande taille, de compresser ces images afin de réduire le poids total du document, et de récupérer une version compressée.

L'application répond aux objectifs suivants :

  • Compression d’images : réduction de la qualité des images pour optimiser la taille du fichier.

  • Interface sécurisée : accès à l’interface uniquement via un mot de passe.

  • Contrôle de la qualité de compression : l’utilisateur peut choisir le niveau de qualité souhaité pour les images, permettant de s'adapter à différents besoins de résolution.

Conception et Développement de l’Application

Environnement et technologies utilisées

Cette application a été construite avec les outils et technologies suivants :

  • Python & Flask : utilisés pour gérer le serveur web et les requêtes HTTP.

  • Pillow (PIL) : bibliothèque de traitement d’images permettant de compresser les images.

  • Bootstrap : framework CSS pour structurer l'interface utilisateur avec un design moderne et responsive.

  • HTML : langage de balisage pour la structure des pages.

  • GitBook : utilisé pour documenter le projet et suivre les modifications.

Architecture de l’application

L'application est organisée autour des fichiers et dossiers suivants :

  • app.py : fichier principal de l'application contenant le code de l'API Flask, la logique de compression, et la gestion des utilisateurs.

  • templates/ : dossier contenant les fichiers HTML pour l'interface utilisateur.

  • uploads/ et compressed/ : dossiers de stockage temporaire pour les fichiers téléchargés et compressés.

Le flux de travail de l'application est conçu comme suit :

  1. L’utilisateur se connecte en fournissant un mot de passe. S'il est correct, il est redirigé vers l’interface de téléchargement.

  2. L’utilisateur peut ensuite glisser-déposer ou sélectionner un fichier Excel contenant des images.

  3. La compression des images s’effectue en arrière-plan avec le niveau de qualité spécifié par l'utilisateur.

  4. Le fichier Excel compressé est proposé en téléchargement.

Développement de chaque fonctionnalité

Sécurité (Authentification par mot de passe)

L'application utilise un système de session basé sur Flask pour gérer l'authentification. La page de connexion protège l'accès à l'interface principale. L'utilisateur doit entrer un mot de passe unique pour accéder aux fonctionnalités de l'application. En cas de mot de passe incorrect, un message d'erreur s'affiche pour inviter à réessayer.

Mise en place : le code utilise session['logged_in'] pour vérifier si un utilisateur est connecté. La route /login traite les demandes de connexion et /logout permet la déconnexion sécurisée.

Téléchargement et compression des images

Le cœur de l'application consiste à permettre à l'utilisateur de télécharger un fichier Excel et à compresser les images à l'intérieur. Voici comment cela fonctionne :

  1. Téléchargement du fichier : Le fichier Excel est chargé dans le dossier uploads via un champ de téléchargement.

  2. Compression des images : À l'aide de la bibliothèque Pillow, chaque image est compressée selon la qualité choisie par l’utilisateur. Les images sont ensuite réintégrées dans le fichier Excel.

  3. Gestion de la qualité : Un champ de saisie permet à l’utilisateur de spécifier une qualité de compression entre 1 et 100, 1 étant le niveau de compression maximal (qualité la plus basse) et 100 étant la qualité la plus élevée.

Interface Utilisateur avec Bootstrap

Bootstrap est utilisé pour créer une interface utilisateur intuitive et responsive. Les éléments sont structurés pour une interaction simple et accessible, incluant :

  • Formulaire de connexion : Champ de mot de passe avec messages d’erreur en cas de tentative incorrecte.

  • Formulaire de téléchargement : Champ de téléchargement de fichier et champ de qualité de compression.

  • Boutons : Boutons stylisés pour soumettre le fichier, choisir la qualité de compression, et se déconnecter.

Chaque composant de l’interface suit le style Bootstrap, garantissant une expérience utilisateur moderne et professionnelle.

Conclusion et Prochaines étapes

Cette application répond efficacement aux besoins de réduction de la taille des fichiers Excel contenant des images. Elle simplifie la gestion de fichiers Excel volumineux en offrant une compression adaptée, tout en restant facile à utiliser.

Possibilités d’évolution :

  • Améliorer la sécurité : Ajouter une gestion multi-utilisateurs et un chiffrement pour le mot de passe.

  • Créer une API REST : Permettre l’accès à la compression via des requêtes API, facilitant l'intégration avec d’autres systèmes.

  • Gestion de plusieurs fichiers simultanés : Ajouter la possibilité de traiter plusieurs fichiers en une seule session.

Application

import os
from flask import Flask, request, render_template, send_file, redirect, url_for, session, flash
import openpyxl
from openpyxl.drawing.image import Image
from PIL import Image as PILImage
import io

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'uploads'
app.config['COMPRESSED_FOLDER'] = 'compressed'
app.secret_key = 'private_key'

# Crée les dossiers si pas la
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
os.makedirs(app.config['COMPRESSED_FOLDER'], exist_ok=True)

PASSWORD = "password"

def compress_image(image_stream, quality=30):
    original_image = PILImage.open(image_stream)
    compressed_image_io = io.BytesIO()
    original_image.save(compressed_image_io, format="JPEG", quality=quality)
    compressed_image_io.seek(0)
    return compressed_image_io

def process_excel_images(file_path, quality=30):
    workbook = openpyxl.load_workbook(file_path)
    for sheet_name in workbook.sheetnames:
        sheet = workbook[sheet_name]
        images_to_compress = [image for image in sheet._images]
        sheet._images = []
        
        for image in images_to_compress:
            compressed_image_io = compress_image(image.ref, quality=quality)
            new_image = Image(compressed_image_io)
            new_image.anchor = image.anchor
            sheet.add_image(new_image)
    
    compressed_file_path = os.path.join(app.config['COMPRESSED_FOLDER'], 'compressed_' + os.path.basename(file_path))
    workbook.save(compressed_file_path)
    return compressed_file_path

@app.route('/', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        if request.form['password'] == PASSWORD:
            session['logged_in'] = True
            return redirect(url_for('upload_file'))
        else:
            flash("Mot de passe incorrect, réessayez.", "danger")
    return render_template('login.html')

@app.route('/upload')
def upload_file():
    if not session.get('logged_in'):
        return redirect(url_for('login'))
    return render_template('upload.html')

@app.route('/compress', methods=['POST'])
def compress_file():
    if not session.get('logged_in'):
        return redirect(url_for('login'))
    
    if 'file' not in request.files:
        flash("Aucun fichier sélectionné.", "warning")
        return redirect(url_for('upload_file'))
    file = request.files['file']
    if file.filename == '':
        flash("Aucun fichier sélectionné.", "warning")
        return redirect(url_for('upload_file'))
    
    quality = int(request.form.get('quality', 30))
    
    file_path = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
    file.save(file_path)
    
    compressed_file_path = process_excel_images(file_path, quality=quality)
    return send_file(compressed_file_path, as_attachment=True)

@app.route('/logout')
def logout():
    session.pop('logged_in', None)
    return redirect(url_for('login'))

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5555)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Connexion</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
    <h2 class="text-center">Connexion</h2>
    <form action="/" method="post" class="mx-auto" style="max-width: 400px;">
        {% with messages = get_flashed_messages(with_categories=true) %}
            {% if messages %}
                {% for category, message in messages %}
                    <div class="alert alert-{{ category }}">{{ message }}</div>
                {% endfor %}
            {% endif %}
        {% endwith %}
        <div class="mb-3">
            <label for="password" class="form-label">Mot de passe</label>
            <input type="password" class="form-control" id="password" name="password" required>
        </div>
        <button type="submit" class="btn btn-primary w-100">Se connecter</button>
    </form>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Compresser les Images d'un Excel</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
    <h2 class="text-center">Compresser les Images d'un Fichier Excel</h2>
    <form action="/compress" method="post" enctype="multipart/form-data" class="mx-auto" style="max-width: 600px;">
        <div class="mb-3">
            <label for="file" class="form-label">Sélectionnez votre fichier Excel</label>
            <input type="file" class="form-control" name="file" id="file" accept=".xlsx" required>
        </div>
        <div class="mb-3">
            <label for="quality" class="form-label">Qualité de compression (1-100)</label>
            <input type="number" name="quality" id="quality" min="1" max="100" value="30" class="form-control">
        </div>
        <button type="submit" class="btn btn-primary w-100">Compresser et Télécharger</button>
    </form>
    <div class="mt-4 text-center">
        <a href="/logout" class="btn btn-secondary">Déconnexion</a>
    </div>
</div>
</body>
</html>
PreviousMonitoringNextInventaire

Last updated 5 months ago

21KB
Excel.zip
archive