From fd41af641b34badf017762d67f1070a738384251 Mon Sep 17 00:00:00 2001 From: "13621160019@163.com" <13621160019@163.com> Date: Wed, 10 Mar 2021 19:36:04 +0800 Subject: [PATCH 1/2] added translation for German --- admin/app/translations.js | 1051 ++++++++++++++++++++++++++++++++++++- 1 file changed, 1049 insertions(+), 2 deletions(-) diff --git a/admin/app/translations.js b/admin/app/translations.js index 01d0985f..2c12e3af 100644 --- a/admin/app/translations.js +++ b/admin/app/translations.js @@ -373,7 +373,7 @@ function config($translateProvider) { SROSS: 'shutdown rate of standard status on non-working days', USER: 'User', - + TEAM: 'Team', ADD_TEAM: 'Add Team', EDIT_TEAM: 'Edit Team', @@ -1429,7 +1429,7 @@ function config($translateProvider) { SROSS: '非生产日标准状态下关闭率', USER: '用户', - + TEAM: '班组', ADD_TEAM: '添加班组', @@ -2098,6 +2098,1053 @@ function config($translateProvider) { }, }) + .translations('de', { + MY_EMS_NAME: 'MyEMS', + LANGUAGE: 'Sprache', + FULLSCREEN: 'Vollbildanzeige', + ENTER_SYSTEM: 'Geben Sie das Managementsystem ein', + EXITFULLSCREEN: 'Beenden Sie den Vollbildmodus', + LOGOUT: 'ausfallen', + COMMON: { + EXECUTE: 'durchgeführt', + EDIT: 'ändern', + DELETE: 'löschen', + ACTION: 'Betriebs', + PLACEHOLDER: 'Bitte auswählen oder suchen ...', + SPACE: 'Raum', + EQUIPMENT: 'Ausrüstung', + COMBINED_EQUIPMENT: 'Kombinationsausrüstung', + TENANT: 'Mieter', + STORE: 'Geschäft', + SHOPFLOOR: 'Werkstatt', + DATA_SOURCE: 'Datenquelle', + SENSOR: 'Sensor', + ENERGY_FLOW_DIAGRAM: 'Energieflussdiagramm', + + UTILITY: 'Nützlichkeit', + PERIOD: { + LABEL: 'Bereich auswählen', + YEAR: 'Jahr', + MONTH: 'Monat', + DAY: 'Tag', + HOUR: 'Zeit', + }, + DATE: 'Datum', + BASEMETER: 'Benchmark-Tabelle', + ANALYSISMETER: 'Analysetabelle', + ANALYSIS: { + LABEL: 'Anzeigemethode', + ENERGY: 'Energieverbrauch', + COST: 'Kosten' + }, + ENERGYFLOW: { + LABEL: 'Energiefluss', + INCOME: 'Zufluss', + OUTPUT: 'Abfluss' + }, + COMPARE: { + LABEL: 'Vergleichsmethode', + TREND: 'Trend', + COMPARE: 'Vergleichen Sie' + }, + STATISTICS: { + LABEL: 'Analyse Methode', + COMMON: 'Routineanalyse', + KEYDEVICE: 'Nach Geräteattribut', + WORKINGDAY: 'Tag ohne Produktion', + STATUS: 'Energieverbrauch nach Gerätestatus', + CPU: 'Energieverbrauch pro Einheit', + }, + CHARTTYPE: { + LABEL: 'Diagrammanzeigemodus', + COLUMN: 'Histogramm', + LINE: 'Graph' + }, + TARIFF: { + TOPPEAK: 'Trinkgeld', + ONPEAK: 'Gipfel', + OFFPEAK: 'Senke', + MIDPEAK: 'Niveau' + } + }, + REPORT: { + REPORT: 'Bericht', + REPORT_LIST: 'Berichtsliste', + CREATE_TIME: 'Erstellungszeitpunkt', + FILE_NAME: 'Dateinamen', + TABLE: { + ENERGYDATA: 'detaillierte Daten', + TIME: 'Zeit', + HOUR: 'Zeit', + TOTAL: 'Zusammenfassung' + } + }, + FDD: { + ID: 'ID', + RULE: 'Regel', + EMAIL_MESSAGE: 'Mail-Informationen', + TEXT_MESSAGE: 'SMS-Nachricht', + WEB_MESSAGE: 'Webseiteninformationen', + WECHAT_MESSAGE: 'WeChat Informationen', + RECIPIENT: 'Empfänger', + + ALARM_LIST: 'Zeigen Sie die Alarmliste an', + RULE_LIST: 'Liste der Regeln', + ADD_RULE: 'Regel hinzufügen', + EDIT_RULE: 'Regeln bearbeiten', + FDD_CODE: 'Diagnosecode', + CATEGORY: 'Diagnosekategorie', + PRIORITY: 'Alarmpriorität', + CHANNEL: 'Alarmkanal', + IS_ENABLED: 'Alarmschalter', + EXPRESSION: 'Ausdruck', + MESSAGE_TEMPLATE: 'Nachrichtenvorlage', + DES_EXPRESSION: 'Klicken Sie auf "Bearbeiten"', + + SMS_ALARM_LIST: 'SMS-Alarmliste', + RECIPIENT_NAME: 'Empfänger', + RECIPIENT_MOBILE: 'Telefonnummer', + ALARM_MESSAGE: 'Alarminformationen', + ALARM_TIME: 'Weckzeit', + SCHEDULE_TIME: 'Geplante Sendezeit', + ACKNOWLEDGE_CODE: 'Bestätigungscode', + + EMAIL_ALARM_LIST: 'Mail-Alarmliste', + EMAIL: 'Briefkasten', + TOPIC: 'Thema', + ATTACHMENT_NAME: 'Zubehörname', + ACKNOWLEDGE_MESSAGE: 'Bestätigungsmeldung', + ACKNOWLEDGE: 'bestätigen', + WEB_ALARM_LIST: 'Webseiten-Alarmliste', + WECHAT_ALARM_LIST: 'WeChat Alarmliste', + WECHAT_ID: 'Wir chatten Nummer', + MESSAGE_FORMAT: 'Informationsformat', + ACKNOWLEDGE_ALARM: 'Bestätigen Sie den Alarm?', + }, + MENU: { + SPACE: 'Raumenergieverbrauch', + MAINEQUIPMENT: 'Energieverbrauch der Schlüsselausrüstung', + PRODUCT: 'Energieverbrauch pro Produkteinheit', + EQUIPMENTSTATUS: 'Gerätestatus Energieverbrauch', + EQUIPMENT_DETAILS: { + EQUIPMENT_DETAILS: 'Gerätedetails', + CHILLER: 'Kühleinheit', + AIR_COMPRESSOR: 'Luftkompressor', + AIR_HANDLING_UNIT: 'Lüftungsgerät', + CHILLED_WATER_PUMP: 'Kühlwasserpumpen', + COOLING_TOWER: 'Kühlturm', + COOLING_WATER_PUMP: 'Kühlwasserpumpe', + HEAT_PUMP: 'Wärmepumpe', + GROUND_SOURCE_HEAT_PUMP: 'Erdwärmepumpe', + STEAM_BOILER: 'Dampfer', + }, + FDD: { + FDD: 'Fehlererkennung und -diagnose', + RULE: 'Regelverwaltung', + MESSAGEALARM: 'SMS-Alarm', + EMAILALARM: 'E-Mail-Alarm', + WEBALARM: 'Webseitenalarm', + WECHATALARM: 'WeChat Alarm', + }, + VERIFICATION: { + VERIFICATION: 'Datenvalidierung', + METER_VALIDATE: 'Zählerstand', + METER_ENERGY: 'Tabelle Energieverbrauch', + METER_STATUS: 'Tabellenstatus', + GATEWAY: 'Tor', + }, + SETTINGS: { + BASIC: 'Grundeinstellungen', + SETTINGS: 'Systemmanagement', + SPACE: 'Raum-Management', + TENANT: 'Mietermanagement', + STORE: 'Geschäftsleitung', + SHOPFLOOR: 'Werkstattmanagement', + EQUIPMENT: 'Gerätemanagement', + COMBINED_EQUIPMENT: 'Kombiniertes Gerätemanagement', + METER: 'Zählerverwaltung', + SENSOR: 'Sensorverwaltung', + GATEWAY: 'Gateway-Verwaltung', + DATASOURCE: 'Datenquellenverwaltung', + COSTCENTER: 'Kostenstellenmanagement', + PRODUCT: 'Produkt Management', + CATEGORY: 'Energieklassifizierungsmanagement', + ENERGY_FLOW_DIAGRAM: 'Energieflussdiagramm-Management', + DISTRIBUTION_SYSTEM: 'Verwaltung des Verteilungssystems', + TARIFF: 'Energieratenmanagement', + EMAIL_SERVER: 'Mailserver-Einstellungen', + GSM_MODEM: 'SMS-Moduleinstellungen', + CONTACT: 'Kontaktmanagement', + KNOWLEDGEFILE: 'Wissensdatenbankverwaltung' + }, + USERSETTING: { + USERSETTING: 'Benutzer und Berechtigungen', + USER: 'Benutzereinstellungen', + PRIVILEGE: 'Berechtigungseinstellungen' + } + }, + DATETIMERANGE: { + APPLY: 'bestimmen', + CANCEL: 'stornieren', + CUSTOMRANGE: 'anpassen', + TODAY: 'heutige Tag', + YESTODAY: 'gestern', + BYESTODAY: 'Vorgestern', + CURRENTMONTH: 'diesen Monat', + LASTMONTH: 'Letzten Monat', + CURRENTYEAR: 'Dieses Jahr', + LASTYEAR: 'Letztes Jahr' + }, + LOGIN: { + USERLOGIN: 'Benutzer-Anmeldung', + USERNAME: 'Nutzername', + PASSWORD: 'Passwort', + LOGIN: 'Einloggen', + TITLE: 'Energiemanagementsystem', + }, + SETTING: { + KNOWLEDGEFILE: 'Wissensdatei', + ID: 'ID', + ACTION: 'Betriebs', + ADD: 'Hinzufügen', + BIND_PROPERTY: 'Bindungseigenschaften', + EDIT: 'ändern', + DELETE: 'löschen', + SELECT: 'wählen', + RESET: 'Zurücksetzen', + SAVE: 'speichern', + CANCEL: 'stornieren', + DOWNLOAD: 'herunterladen', + REFRESH: 'Aktualisierung', + RETURN: 'Rückkehr', + YES: 'Ja', + NO: 'Nein', + ON: 'anmachen', + OFF: 'Herunterfahren', + OK: 'bestimmen', + ADD_SPACE: 'Platz hinzufügen', + ADD_TENANT: 'Mieter hinzufügen', + ADD_STORE: 'Laden hinzufügen', + ADD_METER: 'Messgerät hinzufügen', + ADD_VIRTUAL_METER: 'Virtuelle Tabelle hinzufügen', + ADD_OFFLINE_METER: 'Offline-Tabelle hinzufügen', + ADD_POINT: 'Punkt hinzufügen', + ADD_COSTCENTER: 'Kostenstelle hinzufügen', + ADD_TARIFF: 'Rate hinzufügen', + ADD_CATEGORY: 'Energieklassifizierung hinzufügen', + ADD_ENERGY_ITEM: 'Unterelemente zum Energieverbrauch hinzufügen', + ADD_TARIFF: 'Rate hinzufügen', + ADD_EMAIL_RECIPIENT: 'Empfänger hinzufügen', + ADD_SMS_RECIPIENT: 'Kontakt hinzufügen', + ADD_CONTACT: 'Kontakt hinzufügen', + ADD_EMAIL_SERVER: 'Mail-Server hinzufügen', + ADD_GSM_MODEM: 'SMS-Modul hinzufügen', + + EDIT_SPACE: 'Leerzeichen bearbeiten', + EDIT_TENANT: 'Mieter bearbeiten', + EDIT_STORE: 'Speicher bearbeiten', + EDIT_METER: 'Messgerät bearbeiten', + EDIT_VIRTUAL_METER: 'Virtuelle Tabelle bearbeiten', + EDIT_OFFLINE_METER: 'Offline-Tabelle bearbeiten', + EDIT_POINT: 'Punkt bearbeiten', + EDIT_COSTCENTER: 'Kostenstelle bearbeiten', + EDIT_TARIFF: 'Bearbeitungsrate', + EDIT_CATEGORY: 'Energieklassifizierung bearbeiten', + EDIT_ENERGY_ITEM: 'Unterelemente zum Energieverbrauch bearbeiten', + EDIT_EMAIL_RECIPIENT: 'Empfänger bearbeiten', + EDIT_SMS_RECIPIENT: 'Kontakt bearbeiten', + EDIT_CONTACT: 'Kontakt bearbeiten', + EDIT_EMAIL_SERVER: 'Postfachserver bearbeiten', + EDIT_GSM_MODEM: 'SMS-Modul bearbeiten', + EDIT_PARAM_COMBINED_EQUIPMENT: 'Bearbeiten Sie die Parameter des Kombinationsgeräts', + EDIT_PARAM_EQUIPMENT: 'Geräteparameter bearbeiten', + EDIT_PARAM_SPACE: 'Raumparameter bearbeiten', + + REQUIRES_AUTHENTICATION: 'Authentifizierung erforderlich', + SELECT_SPACE: 'Bitte wählen Sie eine Energieeinheit', + SELECT_DATE: 'Bitte wählen Sie ein Datum', + SELECT_SPACE: 'Bitte wählen Sie ein Leerzeichen', + SELECT_TENANT: 'Bitte Mieter auswählen', + SELECT_STORE: 'Bitte wählen Sie ein Geschäft', + SELECT_TIMEZONE: 'Bitte wählen Sie eine Zeitzone', + SELECT_CATEGORY: 'Bitte wählen Sie die Energieklassifizierung', + SELECT_ENERGY_ITEM: 'Bitte wählen Sie den Energieverbrauch', + SELECT_COSTCENTER: 'Bitte wählen Sie eine Kostenstelle', + SELECT_METER: 'Bitte wählen Sie einen Zähler', + IS_INPUT_COUNTED: 'Zusammenfassung der Verbrauchsbeteiligung', + IS_OUTPUT_COUNTED: 'Zusammenfassung der Beteiligung an der Energieabgabe', + BIND_METER: 'Bindemessgerät', + BIND_POINT: 'Datenpunkte binden', + BIND_SENSOR: 'Bindungssensor', + BIND_TARIFF: 'Bindungsrate', + PHONE_ID_FORMAT: 'Bitte geben Sie die Landesvorwahl ein: z. B. 0086 + Handynummer', + + INPUT_NAME: 'Bitte geben Sie einen Namen ein', + INPUT_AREA: 'Bitte betreten Sie den Bereich', + INPUT_UNIT: 'Bitte geben Sie eine Einheit ein', + INPUT_CONTACT: 'Bitte geben Sie einen Kontakt ein', + INPUT_EXPRESSION: 'Bitte geben Sie einen Ausdruck ein', + INPUT_SERIAL_NUMBER: 'Bitte geben sie die Seriennummer ein', + INPUT_KGCE: 'Bitte geben Sie den Standardkohlekoeffizienten ein', + INPUT_KGCO2E: 'Bitte geben Sie den CO2-Emissionsfaktor ein', + INPUT_TAG: 'Bitte geben Sie ein Etikett ein', + INPUT_HOST: 'Bitte geben Sie den Server ein', + INPUT_PORT: 'Bitte geben Sie die Portnummer ein', + INPUT_USER_NAME: 'Bitte geben sie einen Benutzernamen ein', + INPUT_FROM_ADDR: 'Bitte geben Sie die Absenderadresse ein', + INPUT_SERIAL_PORT: 'Bitte geben Sie die serielle Schnittstelle ein', + INPUT_BAUD_RATE: 'Bitte geben Sie die Baudrate ein', + + EMAIL_SERVER: 'Mail-Server', + GSM_MODEM: 'SMS-Modul', + INVALID_FORMAT: 'Falsches Format', + INVALID_FROM_ADDR: 'Falsche Absenderadresse', + INVALID_BAUD_RATE: 'Falsche Baudrate', + NOT_NULLABLE: 'Darf nicht leer sein', + MASTER_METER: 'Übersichtstabelle', + METER: 'Meter', + VIRTUAL_METER: 'Virtuelle Tabelle', + OFFLINE_METER: 'Offline-Tabelle', + OFFLINE_METER_FILE: 'Offline-Tabellendatei', + PRODUCT: 'Produkt', + N_S_METER: 'Gebundener Tisch', + N_S_POINT: 'Gebundener Datenpunkt', + N_S_SENSOR: 'Gebundener Sensor', + N_S_TARIFF: 'Gebundene Rate', + TARIFF_LIST: 'Preisliste', + POINT_LIST: 'Datenpunktliste', + SENSOR_LIST: 'Sensorliste', + METER_TYPE: 'Zählertyp', + METER_NAME: 'Zählername', + METER_STATUS: 'Messgerätestatus', + TRASH: 'recyceln können', + DRAG_TO_BIND: 'Bitte ziehen und ablegen, um die Bindung abzuschließen', + DRAG_TO_UNBIND: 'Bitte ziehen Sie in den Papierkorb, um die Bindung aufzuheben', + FINANCIAL_COST: 'Erfassung der finanziellen Allokationskosten', + NAME: 'Name', + AREA: 'Bereich', + UNIT: 'Einheit', + CONTACT: 'Gesprächspartner', + ENERGY_SYSTEM_CONTACT: 'Kontakt zum Energiesystem', + TIMEZONE: 'Zeitzone', + TARIFF: 'Bewertung', + + COSTCENTER: 'Kostenstelle', + CATEGORY: 'Energieklassifizierung', + ENERGY_ITEM: 'Unterpunkt Energieverbrauch', + STATUS: 'Status', + UPLOAD_TIME: 'Upload-Zeit', + SERIAL_NUMBER: 'Ordnungsnummer', + COEF: 'Umrechnungsfaktor', + TAG: 'Etikette', + BASELINE_CPU: 'Basislinie für den Verbrauch von Einheiten', + BASELINE_COST: 'Stückkostenbasis', + EXPRESSION: 'Ausdruck', + VARIABLE_NAME: 'Variablennamen', + POINT: 'Datenpunkt', + KGCE: 'Standardkohlekoeffizient', + KGCO2E: 'CO2-Emissionsfaktor', + + START_DATETIME: 'Startzeit', + START_TIME: 'Anfangszeit', + END_DATETIME: 'Endzeit', + END_TIME: 'Endzeit', + TARIFF_TYPE: 'Tarifart', + TARIFF_NAME: 'Name', + PRICE: 'Preis', + BLOCK: 'Staffelpreis', + TIMEOFUSE: 'Timesharing-Rate', + PEAK_TYPE: 'Feng Guping', + START_AMOUNT: 'Startbetrag', + END_AMOUNT: 'Endbetrag', + + PORT: 'Hafen', + GSM: 'GSM', + SMS: 'SMS', + SERIAL_PORT: 'Adresse der seriellen Schnittstelle', + BAUD_RATE: 'Baudrate', + FROM_ADDR: 'Absenderadresse', + HOST: 'Server', + USER_NAME: 'Nutzername', + + SUSPENDED: 'Bereithalten', + IDLING: 'Probelauf', + RUNNING: 'Lauf', + PARAM_COMBINED_EQUIPMENT: 'Parameterverwaltung für Kombinationsgeräte', + PARAM_EQUIPMENT: 'Verwaltung von Geräteparametern', + PARAM_SPACE: 'Räumliche Parameterverwaltung', + SROSS: 'Schlusskurs unter Standardbedingungen an Nichtproduktionstagen', + + USER: 'Nutzer', + + + TEAM: 'Mannschaft', + ADD_TEAM: 'Füge ein Team hinzu', + EDIT_TEAM: 'Team bearbeiten', + SEARCH: 'suchen nach...', + METER_DATA: 'Zählerdaten', + START_ENERGY: 'Anfangsenergieverbrauchswert', + END_ENERGY: 'Ende des Energieverbrauchs', + // ENERGY_VALUE: 'Energieverbrauchswert', + DIFF_VALUE: 'Unterschied', + }, + CONTACT: { + EMAIL: 'Briefkasten', + PHONE: 'Telefon', + DESCRIPTION: 'Beschreibung (optional)', + INPUT_EMAIL: 'Bitte geben Sie Ihre E-Mail-Adresse ein', + INPUT_PHONE: 'Bitte geben Sie das Telefon ein', + INPUT_DESCRIPTION: 'Bitte geben Sie eine Beschreibung ein', + INVALID_EMAIL: 'Falsches E-Mail-Format (xxx@xxx.xx)', + }, + + COSTCENTER: { + EXTERNAL_ID: 'Externe ID', + INPUT_EXTERNAL_ID: 'Bitte geben Sie eine externe ID ein', + }, + DATA_SOURCE: { + DATA_SOURCE: 'Datenquelle', + ADD_DATA_SOURCE: 'Datenquelle hinzufügen', + EDIT_DATA_SOURCE: 'Datenquelle bearbeiten', + SELECT_DATA_SOURCE: 'Bitte wählen Sie die Datenquelle', + PROTOCOL: 'Protokoll', + CONNECTION: 'Verbindung', + INPUT_PROTOCOL: 'Bitte geben Sie den Protokolltyp ein', + INPUT_CONNECTION: 'Bitte geben Sie die Verbindungsadresse ein', + }, + POINT: { + OBJECT_TYPE: 'Objekttyp', + UNIT: 'Einheit', + HIGH_LIMIT: 'Obergrenze', + LOW_LIMIT: 'Untergrenze', + RATIO: 'Skalierungsfaktor', + IS_TREND: 'Trend speichern', + ADDRESS: 'Adresse (JSON)', + DESCRIPTION: 'Beschreibung (optional)', + INPUT_HIGH_LIMIT: 'Bitte geben Sie das obere Limit ein', + INPUT_LOW_LIMIT: 'Bitte geben Sie die Untergrenze ein', + INPUT_RATIO: 'Bitte geben Sie den Skalierungsfaktor ein', + INPUT_ADDRESS: 'Bitte geben Sie die Adresse ein', + INPUT_DESCRIPTION: 'Bitte geben Sie eine Beschreibung ein', + }, + + DISTRIBUTION_SYSTEM: { + DISTRIBUTION_SYSTEM: 'Vertriebssystem', + ADD_DISTRIBUTION_SYSTEM: 'Stromverteilungssystem hinzufügen', + EDIT_DISTRIBUTION_SYSTEM: 'Stromverteilungssystem bearbeiten', + SELECT_DISTRIBUTION_SYSTEM: 'Bitte wählen Sie das Stromverteilungssystem', + SVG: 'SVG', + INPUT_SVG: 'Bitte geben Sie SVG ein', + DESCRIPTION: 'Beschreibung (optional)', + DISTRIBUTION_CIRCUIT: 'Verteilerkreis', + N_S_DISTRIBUTION_CIRCUIT: 'Eigener Verteilerkreis', + ADD_DISTRIBUTION_CIRCUIT: 'Verteilerkreis hinzufügen', + EDIT_DISTRIBUTION_CIRCUIT: 'Stromverteilungskreis bearbeiten', + SELECT_DISTRIBUTION_CIRCUIT: 'Bitte wählen Sie den Verteilerkreis', + DISTRIBUTION_CIRCUIT_ID: 'ID', + DISTRIBUTION_CIRCUIT_NAME: 'Name', + INPUT_DISTRIBUTION_CIRCUIT_NAME: 'Bitte geben Sie einen Namen ein', + DISTRIBUTION_CIRCUIT_DISTRIBUTION_ROOM: 'Stromverteilungsraum', + INPUT_DISTRIBUTION_CIRCUIT_DISTRIBUTION_ROOM: 'Bitte betreten Sie den Stromverteilungsraum', + DISTRIBUTION_CIRCUIT_SWITCHGEAR: 'Verteilerschrank', + INPUT_DISTRIBUTION_CIRCUIT_SWITCHGEAR: 'Bitte betreten Sie den Stromverteilungsschrank', + DISTRIBUTION_CIRCUIT_PEAK_LOAD: 'Maximale Kapazität (KW)', + INPUT_DISTRIBUTION_CIRCUIT_PEAK_LOAD: 'Bitte geben Sie die maximale Kapazität (KW) ein.', + DISTRIBUTION_CIRCUIT_PEAK_CURRENT: 'Maximaler Strom (A)', + INPUT_DISTRIBUTION_CIRCUIT_PEAK_CURRENT: 'Bitte geben Sie den Maximalstrom ein (A)', + DISTRIBUTION_CIRCUIT_CUSTOMERS: 'Nutzer', + INPUT_DISTRIBUTION_CIRCUIT_CUSTOMERS: 'Bitte geben Sie den Benutzer ein', + DISTRIBUTION_CIRCUIT_METERS: 'Ausgehender Zähler', + INPUT_DISTRIBUTION_CIRCUIT_METERS: 'Bitte geben Sie den Auslasszähler ein', + PREVIEW: 'Vorschau', + N_S_PREVIEW: 'Vorschau', + }, + ENERGY_FLOW_DIAGRAM: { + ADD_ENERGY_FLOW_DIAGRAM: 'Energieflussdiagramm hinzufügen', + EDIT_ENERGY_FLOW_DIAGRAM: 'Energieflussdiagramm bearbeiten', + SELECT_ENERGY_FLOW_DIAGRAM: 'Bitte wählen Sie das Energieflussdiagramm', + NODE: 'Knoten', + N_S_NODE: 'Knoten besitzen', + ADD_NODE: 'Knoten hinzufügen', + EDIT_NODE: 'Knoten bearbeiten', + NODE_ID: 'Knoten-ID', + NODE_NAME: 'Knotenname', + INPUT_NODE_NAME: 'Bitte geben Sie den Knotennamen ein', + LINK: 'Verknüpfung', + N_S_LINK: 'Zugehörigkeit zum Link', + LINK_ID: 'Link ID', + ADD_LINK: 'Fügen Sie einen Link hinzu', + EDIT_LINK: 'Link bearbeiten', + SOURCE_NODE: 'Quellknoten', + TARGET_NODE: 'Zielknoten', + METER: 'Meter', + PREVIEW: 'Vorschau', + N_S_PREVIEW: 'Vorschau', + }, + COMBINED_EQUIPMENT: { + ADD_COMBINED_EQUIPMENT: 'Fügen Sie ein Kombinationsgerät hinzu', + EDIT_COMBINED_EQUIPMENT: 'Kombinationsgerät bearbeiten', + SELECT_COMBINED_EQUIPMENT: 'Bitte wählen Sie ein Kombinationsgerät', + COST_CENTER: 'Kostenstelle', + SELECT_COST_CENTER: 'Bitte wählen Sie eine Kostenstelle', + DESCRIPTION: 'Beschreibung (optional)', + BIND_EQUIPMENT: 'Gerät binden', + N_S_EQUIPMENT: 'Gebundenes Gerät', + EQUIPMENT_LIST: 'Geräteliste', + INPUT_METER: 'Bitte geben Sie die Tabelle ein', + INPUT_DESCRIPTION: 'Bitte geben Sie eine Beschreibung ein', + OUTPUT_METER: 'Ausgabetabelle', + PARAMETER: 'Parameter', + BIND_PARAMETER: 'Bindungsparameter', + ADD_PARAMETER: 'Parameter hinzufügen', + EDIT_PARAMETER: 'Parameter bearbeiten', + N_S_PARAMETER: 'Enthaltene Parameter', + PARAMETER_ID: 'ID', + PARAMETER_NAME: 'Name', + INPUT_PARAMETER_NAME: 'Bitte geben Sie einen Namen ein', + PARAMETER_TYPE: 'Arten von', + SELECT_PARAMETER_TYPE: 'Wählen Sie einen Typ', + PARAMETER_TYPE: 'Arten von', + CONSTANT: 'Konstanter Wert', + POINT: 'Datenpunkt', + SELECT_POINT: 'Datenpunkt auswählen', + FRACTION: 'Fraktion', + PARAMETER_CONSTANT: 'Konstante', + PARAMETER_POINT: 'Datenpunkt', + PARAMETER_NUMERATOR_METER: 'Molekularmessgerät', + PARAMETER_DENOMINATOR_METER: 'Nenner Meter', + }, + EQUIPMENT: { + ADD_EQUIPMENT: 'Gerät hinzufügen', + EDIT_EQUIPMENT: 'Gerät bearbeiten', + SELECT_EQUIPMENT: 'Bitte wählen Sie ein Gerät', + COST_CENTER: 'Kostenstelle', + SELECT_COST_CENTER: 'Bitte wählen Sie eine Kostenstelle', + DESCRIPTION: 'Beschreibung (optional)', + INPUT_METER: 'Bitte geben Sie die Tabelle ein', + INPUT_DESCRIPTION: 'Bitte geben Sie eine Beschreibung ein', + OUTPUT_METER: 'Ausgabetabelle', + PARAMETER: 'Parameter', + BIND_PARAMETER: 'Bindungsparameter', + ADD_PARAMETER: 'Parameter hinzufügen', + EDIT_PARAMETER: 'Parameter bearbeiten', + N_S_PARAMETER: 'Enthaltene Parameter', + PARAMETER_ID: 'ID', + PARAMETER_NAME: 'Name', + INPUT_PARAMETER_NAME: 'Bitte geben Sie einen Namen ein', + PARAMETER_TYPE: 'Arten von', + SELECT_PARAMETER_TYPE: 'Wählen Sie einen Typ', + PARAMETER_TYPE: 'Arten von', + CONSTANT: 'Konstanter Wert', + POINT: 'Datenpunkt', + SELECT_POINT: 'Datenpunkt auswählen', + FRACTION: 'Fraktion', + PARAMETER_CONSTANT: 'Konstante', + PARAMETER_POINT: 'Datenpunkt', + PARAMETER_NUMERATOR_METER: 'Molekularmessgerät', + PARAMETER_DENOMINATOR_METER: 'Nenner Meter', + }, + GATEWAY: { + GATEWAY: 'Tor', + TOKEN: 'Zeichen', + SELECT_GATEWAY: 'Wählen Sie ein Gateway', + ADD_GATEWAY: 'Gateway hinzufügen', + EDIT_GATEWAY: 'Gateway bearbeiten', + }, + SPACE: { + PARENT_SPACE: 'Überlegen', + AREA: 'Bereich', + INPUT_AREA: 'Bitte betreten Sie den Bereich', + DESCRIPTION: 'Beschreibung (optional)', + INPUT_DESCRIPTION: 'Bitte geben Sie eine Beschreibung ein', + CURRENT_SELECTED_SPACE: 'Derzeit ausgewählter Platz', + CHILD_SPACES: 'Unterraum', + BIND_COMBINED_EQUIPMENT: 'Kombinationsgerät binden', + N_S_COMBINED_EQUIPMENT: 'Gebundenes Kombinationsgerät', + COMBINED_EQUIPMENT_LIST: 'Liste der Kombinationsgeräte', + BIND_EQUIPMENT: 'Gerät binden', + N_S_EQUIPMENT: 'Gebundenes Gerät', + EQUIPMENT_LIST: 'Geräteliste', + BIND_COMBINED_EQUIPMENT: 'Kombinationsgerät binden', + N_S_COMBINED_EQUIPMENT: 'Gebundenes Kombinationsgerät', + COMBINED_EQUIPMENT_LIST: 'Liste der Kombinationsgeräte', + BIND_TENANT: 'Mieter binden', + N_S_TENANT: 'Gebundener Mieter', + TENANT_LIST: 'Mieterliste', + BIND_STORE: 'Laden binden', + N_S_STORE: 'Gebundener Laden', + STORE_LIST: 'Liste speichern', + BIND_SHOPFLOOR: 'Bindungswerkstatt', + N_S_SHOPFLOOR: 'Gebundene Werkstatt', + SHOPFLOOR_LIST: 'Werkstattliste', + }, + TENANT: { + BUILDINGS: 'Gebäude', + FLOORS: 'Fußboden', + ROOMS: 'Zimmer', + TYPE: 'Mietertyp', + IS_KEY_TENANT: 'Ob der Hauptmieter', + LEASE_NUMBER: 'Mietnummer', + LEASE_START_DATETIME: 'Datum und Uhrzeit des Mietbeginns', + LEASE_END_DATETIME: 'Datum und Uhrzeit des Leasingendes', + IS_IN_LEASE: 'Mieten Sie?', + DESCRIPTION: 'Beschreibung (optional)', + INPUT_BUILDINGS: 'Bitte betreten Sie das Gebäude', + INPUT_FLOORS: 'Bitte betreten Sie den Boden', + INPUT_ROOMS: 'Bitte betreten Sie den Raum', + INPUT_LEASE_NUMBER: 'Bitte geben Sie die Mietnummer ein', + INPUT_DESCRIPTION: 'Bitte geben Sie eine Beschreibung ein', + }, + STORE: { + ADDRESS: 'Adresse', + LATITUDE: 'Breite', + LONGITUDE: 'Längengrad', + TYPE: 'Speichertyp', + DESCRIPTION: 'Beschreibung (optional)', + INPUT_ADDRESS: 'Bitte geben Sie die Adresse ein', + INPUT_LATITUDE: 'Bitte geben Sie den Breitengrad ein', + INPUT_LONGITUDE: 'Bitte geben Sie den Längengrad ein', + INPUT_DESCRIPTION: 'Bitte geben Sie eine Beschreibung ein', + }, + SHOPFLOOR: { + ADD_SHOPFLOOR: 'Workshop hinzufügen', + EDIT_SHOPFLOOR: 'Bearbeitungsworkshop', + SELECT_SHOPFLOOR: 'Bitte Workshop auswählen', + AREA: 'Bereich', + INPUT_AREA: 'Bitte betreten Sie den Bereich', + DESCRIPTION: 'Beschreibung (optional)', + INPUT_DESCRIPTION: 'Bitte geben Sie eine Beschreibung ein', + BIND_EQUIPMENT: 'Gerät binden', + N_S_EQUIPMENT: 'Gebundenes Gerät', + EQUIPMENT_LIST: 'Geräteliste', + }, + METER: { + HOURLY_LOW_LIMIT: 'Stündliches Minimum (inklusive)', + INPUT_HOURLY_LOW_LIMIT: 'Bitte geben Sie das stündliche Minimum ein', + HOURLY_HIGH_LIMIT: 'Stundenmaximum (inklusive)', + INPUT_HOURLY_HIGH_LIMIT: 'Bitte geben Sie das Stundenmaximum ein', + DESCRIPTION: 'Beschreibung (optional)', + INPUT_DESCRIPTION: 'Bitte geben Sie eine Beschreibung ein', + MASTER_METER: 'Überlegenes Messgerät', + SELECT_MASTER_METER: 'Wählen Sie das übergeordnete Messgerät aus', + TREE_VIEW: 'Baumsicht', + CHILD_METERS: 'Unterer Füllstandsmesser', + }, + SENSOR: { + ADD_SENSOR: 'Sensor hinzufügen', + EDIT_SENSOR: 'Sensor bearbeiten', + DELETE_SENSOR: 'Sensor entfernen', + DESCRIPTION: 'Beschreibung (optional)', + INPUT_DESCRIPTION: 'Bitte geben Sie eine Beschreibung ein', + SELECT_SENSOR: 'Sensor auswählen', + }, + USER: { + USER_LIST: 'Benutzerliste', + PRIVILEGE_LIST: 'Berechtigungsliste', + ADD_USER: 'Nutzer hinzufügen', + EDIT_USER: 'Benutzer bearbeiten', + PRIVILEGE: 'Behörde', + ADD_PRIVILEGE: 'Berechtigungen hinzufügen', + EDIT_PRIVILEGE: 'Berechtigungen bearbeiten', + IS_ADMIN: 'Ist ein Administrator', + DISPLAY_NAME: 'Anzeigename', + USERNAME: 'Nutzername', + PASSWORD: 'Passwort', + RESET_PASSWORD: 'Passwort zurücksetzen', + CHANGE_PASSWORD: 'ändere das Passwort', + OLD_PASSWORD: 'Altes Passwort', + NEW_PASSWORD: 'Neues Passwort', + CONFIRM_PASSWORD: 'Kennwort bestätigen', + INPUT_PASSWORD: 'Bitte geben Sie das Passwort ein', + DIFF_PASSWORD: 'Die beiden eingegebenen Passwörter stimmen nicht überein', + EMAIL: 'Briefkasten', + INPUT_EMAIL: 'Bitte geben Sie Ihre E-Mail-Adresse ein', + INVALID_EMAIL: 'Falsches E-Mail-Format (xxx@xxx.xx)', + }, + KNOWLEDGEFILE: { + KNOWLEDGE_FILE_LIST: 'Liste der Wissensdateien', + UPLOAD_USER: 'hochgeladen von', + UPLOAD_TIME: 'Upload-Zeit', + RESTORE: 'wiederherstellen', + DELETE: 'löschen', + RESTORE_SUCCESS: 'Erfolgreiche Genesung', + RESTORE_FAILED: 'Wiederherstellung fehlgeschlagen' + }, + TOASTER: { + FAILURE: 'Fehler', + FAILURE_TITLE: 'Error', + ERROR: 'Error', + OPTIONS_ERROR: 'Falsche Option', + DATE_RANGE_DIFFERENT: 'Der Datumsbereich ist unterschiedlich.', + SUCCESS: 'Erfolg', + SUCCESS_TITLE: 'Erfolg', + LOGIN_SUCCESS: 'Anmeldung erfolgreich.', + LOGIN_FAILURE: 'Login fehlgeschlagen.', + + SUCCESS_ADD_BODY: 'Fügen Sie {{template}} erfolgreich hinzu.', + SUCCESS_UPDATE_BODY: 'Update {{template}} erfolgreich.', + SUCCESS_DELETE_BODY: '{{Template}} erfolgreich löschen.', + ERROR_ADD_BODY: 'Das Hinzufügen von {{template}} ist fehlgeschlagen.', + ERROR_UPDATE_BODY: 'Update {{template}} fehlgeschlagen.', + ERROR_DELETE_BODY: 'Fehler beim Löschen von {{template}}.', + + USER_PASSWORD: 'Benutzer-Passwort', + BIND_METER_SUCCESS: 'Binden Sie das Messgerät erfolgreich', + UNBIND_METER_SUCCESS: 'Binden Sie das Messgerät erfolgreich ab', + BIND_TARIFF_SUCCESS: 'Bindungsrate ist erfolgreich', + UNBIND_TARIFF_SUCCESS: 'Lösen Sie die Rate erfolgreich', + BIND_POINT_SUCCESS: 'Binden Sie den Datenpunkt erfolgreich', + UNBIND_POINT_SUCCESS: 'Datenpunkt erfolgreich binden', + BIND_SENSOR_SUCCESS: 'Binden Sie den Sensor erfolgreich', + UNBIND_SENSOR_SUCCESS: 'Binden Sie den Sensor erfolgreich ab', + BIND_EQUIPMENT_SUCCESS: 'Binden Sie das Gerät erfolgreich', + UNBIND_EQUIPMENT_SUCCESS: 'Binden Sie das Gerät erfolgreich ab', + BIND_COMBINED_EQUIPMENT_SUCCESS: 'Binden Sie das kombinierte Gerät erfolgreich', + UNBIND_COMBINED_EQUIPMENT_SUCCESS: 'Binden Sie das kombinierte Gerät erfolgreich ab', + BIND_TENANT_SUCCESS: 'Mieter erfolgreich binden', + UNBIND_TENANT_SUCCESS: 'Den Mieter erfolgreich binden', + BIND_STORE_SUCCESS: 'Binden Sie den Laden erfolgreich', + UNBIND_STORE_SUCCESS: 'Binden Sie den Laden erfolgreich auf', + BIND_SHOPFLOOR_SUCCESS: 'Bindungswerkstatt erfolgreich', + UNBIND_SHOPFLOOR_SUCCESS: 'Lösen Sie den Workshop erfolgreich', + }, + SWEET: { + TITLE: 'Bitte bestätigen, um zu löschen?', + TEXT: 'Durch Löschen dieses Artikels werden auch alle zugehörigen Daten gelöscht!', + CONFIRM_BUTTON_TEXT: 'Löschung bestätigen', + CANCEL_BUTTON_TEXT: 'stornieren', + }, + API: { + POINT_TREND: 'Punkttrend', + COMPREHENSIVE_ENERGY: 'Umfassender Energieverbrauch', + KGCE: 'Standardkohle', + TOTAL_CONSUMPTION: 'Gesamtenergieverbrauch', + TOP_PEAK_CONSUMPTION: 'Energieverbrauch während der Stoßzeiten', + ON_PEAK_CONSUMPTION: 'Spitzenenergieverbrauch', + OFF_PEAK_CONSUMPTION: 'Energieverbrauch während der Talperiode', + MID_PEAK_CONSUMPTION: 'Energieverbrauch an Wochentagen', + ACTUAL_UNIT_PRICE: 'Tatsächlicher Stückpreis', + ENERGY_TREND: 'Energieverbrauch', + ENERGY: 'Energieverbrauch', + ACTUAL_VALUE: 'Tatsächlicher absoluter Wert', + ACTUAL_PERCENT: 'Tatsächlicher Anteil', + TARIFF: 'Bewertung', + ENERGY_RATIO: 'Energieverbrauchszusammensetzung', + OUTPUT: 'Ausbeute', + TIME_RATIO: 'Prozentsatz der Zeit', + CHILD_ENERGY_UNIT: 'Energieeinheit unter der Ebene', + ENERGY_UNIT: 'Energie verbrauchende Einheit', + + ANALYSIS_DATE: 'Analysedatum', + BASELINE_DATE: 'Basisdatum', + + STEAM_OUTPUT: 'Dampferzeugung', + STEAM_OUTPUT_VALUE: 'Dampfproduktionswert', + TOTAL_STEAM_VALUE: 'Gesamtstromrechnung + Gesamtleitungswasserrechnung + Dampfproduktionswert', + + ELECTRICITY_MONITORING: 'Leistungsüberwachung', + ENERGY_UNIT_ONE: 'Neuer Park', + ENERGY_UNIT_TWO: 'Power Center der Chemical and Pharmaceutical Group', + ENERGY_UNIT_THREE: 'Power Center der Biologischen Gruppe', + ENERGY_UNIT_FOUR: 'Produktionswerkstatt für chemische Arzneimittelgruppen', + + EQUIPMENT: 'Ausrüstung', + ENERGY_WITH_UNIT: 'Energieverbrauch-kWh', + PUPEC_WITH_UNIT: 'Energieverbrauch pro Produkteinheit-kWh', + RSR: 'Prozentsatz des Energieverbrauchs im Betriebszustand der Geräte', + + AREA: 'Bereich', + WORKING_DAY_ENERGY: 'Täglicher Energieverbrauch der Produktion', + WORKING_DAY_ENERGY_PER_DAY: 'Täglicher Energieverbrauch der Produktion', + NON_WORKING_DAY_ENERGY: 'Unproduktiver täglicher Energieverbrauch', + NON_WORKING_DAY_ENERGY_PER_DAY: 'Täglicher durchschnittlicher Energieverbrauch außerhalb der Produktion', + NWDSSEPD: 'Durchschnittlicher täglicher Energieverbrauchswert des Standardzustands des Nichtproduktionstages', + NWDTECR: 'Theoretische Schließrate der Ausrüstung an Tagen ohne Produktion', + NWDAECR: 'Tatsächliche Abschaltrate der Geräte an Tagen ohne Produktion', + NWDECR: 'Täglicher Energieverbrauch außerhalb der Produktion', + + DATE: 'Datum', + WORKING_DAY_OR_NOT: 'Produktionstag Nichtproduktionstag', + ELECTRICITY_CONSUMPTION: 'Energieverbrauch', + + SINGLE_DEVICE_ENERGY: 'Säulendiagramm zum Energieverbrauch einzelner Geräte', + EQUIPMENT_STATUS_ENERGY_RATIO: 'Prozentsatz des Energieverbrauchs des Gerätezustands', + EQUIPMENT_STATUS_TIME_RATIO: 'Prozentsatz der Gerätezustandszeit', + + + RUNNING_TIME: 'Laufzeit verarbeiten', + RUNNING_ENERGY_CONSUMPTION: 'Energieverbrauch des Verarbeitungsbetriebs', + IDLING_TIME: 'Leerlaufzeit', + IDLING_ENERGY_CONSUMPTION: 'Energieverbrauch im Trockenlauf', + SUSPENDED_TIME: 'Standby-Zeit', + SUSPENDED_ENERGY_CONSUMPTION: 'Standby-Energieverbrauch', + SHUTDOWN_TIME: 'Abschaltzeit', + SHUTDOWN_ENERGY_CONSUMPTION: 'Energieverbrauch abschalten', + + + C_ENERGY_ANALYSIS_SUBJECT: '0. Analysieren Sie den Hauptkörper (untergeordnete Energieverbrauchseinheit).', + C_ENERGY_EQUIPMENT_STATION: '--1. Gerätestation', + C_RUNNING_TIME: '2. Laufzeit verarbeiten', + C_RUNNING_ENERGY_CONSUMPTION: '3. Energieverbrauch des Verarbeitungsbetriebs', + C_ENERGY_IDLING_TIME: '4. Trockenlaufzeit', + C_ENERGY_IDLING_ENERGY_CONSUMPTION: '5. Trockenlauf-Energieverbrauch', + C_ENERGY_SUSPENDED_TIME: '6. Standby-Zeit', + C_ENERGY_SUSPENDED_ENERGY_CONSUMPTION: '7. Standby-Energieverbrauch', + C_ENERGY_SHUTDOWN_TIME: '8. Abschaltzeit', + C_ENERGY_SHUTDOWN_ENERGY_CONSUMPTION: '9. Energieverbrauch abschalten', + C_ENERGY_NPDTECRS: '--8. Standard für den theoretischen Energieverbrauch am Tag ohne Produktion', + C_ENERGY_NPDECR: '--9. Täglicher Energieverbrauch außerhalb der Produktion', + + C_COST_ANALYSIS_SUBJECT: '0. Analysieren Sie den Hauptkörper (untergeordnete Energieverbrauchseinheit).', + C_COST_EQUIPMENT_STATION: '--1. Gerätestation', + C_COST_RUNNING_TIME: '2. Laufzeit verarbeiten', + C_RUNNING_COST: '3. Verarbeitungs- und Betriebskosten', + C_COST_IDLING_TIME: '4. Trockenlaufzeit', + C_COST_IDLING_COST: '5. Leerlaufkosten', + C_COST_SUSPENDED_TIME: '6. Standby-Zeit', + C_COST_SUSPENDED_COST: '7. Standby-Kosten', + C_COST_SHUTDOWN_TIME: '8. Abschaltzeit', + C_COST_SHUTDOWN_COST: '9. Abschaltkosten', + C_COST_NPDTECRS: '--8. Der theoretische Kostenverhältnisstandard für Nichtproduktionstage', + C_COST_NPDECR: '--9. Nichtproduktionskostenquote', + + SUSPENDED: 'Bereithalten', + IDLING: 'Probelauf', + RUNNING: 'Lauf', + SHUTDOWN: 'Herunterfahren', + + NON_WORKING_DAY: 'Unproduktiver Tag', + WORKING_DAY: 'Produktionstag', + + TOTAL: 'Zusammenfassung', + + COMPREHENSIVE_OUTPUT: 'Umfassende Ausgabe', + OUTPUT_TREND: 'Output-Trend', + + COMPREHENSIVE_OUTPUT_VALUE: 'Umfassender Ausgabewert', + OUTPUT_VALUE_TREND: 'Produktionswerttrend', + + KWH: 'KWh', + + YUAN: 'Yuan', + COMPREHENSIVE_COST: 'Umfassende Kosten', + PER_UNIT_COMPREHENSIVE_COST: 'Umfassende Kosten pro Produkteinheit', + TOTAL_COST: 'Gesamtkosten', + TOP_PEAK_COST: 'Trinkgeldgebühr', + ON_PEAK_COST: 'Spitzenzeitgebühr', + OFF_PEAK_COST: 'Talzeitgebühr', + MID_PEAK_COST: 'Normale Zeitgebühr', + + COST: 'Kosten', + COST_TREND: 'Kosten', + COST_RATIO: 'Kostenstruktur', + POC: 'Kostenstruktur', + UNIT_PRICE: "元/千瓦时", + COM: 'Wartungskosten', + + ERROR: 'Error', + BAD_REQUEST: 'Ungültige Anforderung', + NOT_FOUND: 'Nicht gefunden', + EXCEPTION: 'Ausnahme', + COOKIE_IS_EXPIRED: 'Cookie ist abgelaufen', + UNAUTHORIZED: 'nicht autorisiert', + NAME_CONFLICTS: 'Namenskonflikt', + EXTERNAL_ID_CONFLICTS: 'Globaler ID-Konflikt', + DATABASE_ERROR: 'Datenbankfehler', + INVALID_NAME_VALUE: 'Ungültige Benennung', + + TENANT_NOT_FOUND: 'Mieter nicht gefunden', + TENANT_ALREADY_ASSOCIATED_WITH_METER: 'Der Mieter ist bereits mit dem Zähler verbunden', + TENANT_ALREADY_ASSOCIATED_WITH_OFFLINE_METER: 'Der Mandant ist bereits mit der Offline-Tabelle verknüpft', + TENANT_ALREADY_ASSOCIATED_WITH_VIRTUAL_METER: 'Der Mandant ist bereits der virtuellen Tabelle zugeordnet', + TENANT_AND_METER_RELATIONSHIP_NOT_FOUND: 'Mieter- und Zählerbeziehung nicht gefunden', + TENANT_AND_OFFLINE_METER_RELATIONSHIP_NOT_FOUND: 'Mandanten- und Offline-Tabellenbeziehung nicht gefunden', + TENANT_AND_VIRTUAL_METER_RELATIONSHIP_NOT_FOUND: 'Beziehung zwischen Mandant und virtueller Tabelle nicht gefunden', + STORE_NOT_FOUND: 'Kein Geschäft gefunden', + STORE_ALREADY_ASSOCIATED_WITH_METER: 'Das Geschäft ist bereits dem Zähler zugeordnet', + STORE_ALREADY_ASSOCIATED_WITH_OFFLINE_METER: 'Der Speicher wurde der Offline-Tabelle zugeordnet', + STORE_ALREADY_ASSOCIATED_WITH_VIRTUAL_METER: 'Der Speicher wurde der virtuellen Tabelle zugeordnet', + STORE_AND_METER_RELATIONSHIP_NOT_FOUND: 'Die Beziehung zwischen dem Geschäft und dem Zähler wurde nicht gefunden', + STORE_AND_OFFLINE_METER_RELATIONSHIP_NOT_FOUND: 'Die Beziehung zwischen dem Geschäft und der Offline-Tabelle wurde nicht gefunden', + STORE_AND_VIRTUAL_METER_RELATIONSHIP_NOT_FOUND: 'Die Beziehung zwischen dem Geschäft und der virtuellen Tabelle wurde nicht gefunden', + ADVANCE_REPORT_FILE_NOT_FOUND: 'Keine erweiterte Berichtsdatei gefunden', + ASSOCIATED_POINTS_NOT_FOUND: 'Datenpunkt nicht gefunden', + COMPLEX_NOT_FOUND: 'Kein komplexes Produkt gefunden', + COST_CENTER_NOT_FOUND: 'Kostenstelle nicht gefunden', + COST_CENTER_EXTERNAL_ID_EXISTS: 'Externe Kostenstellen-ID ist bereits vorhanden', + COST_CENTER_NAME_EXISTS: 'Kostenstellenname existiert', + DATA_SOURCE_NOT_FOUND: 'Datenquelle nicht gefunden', + DUPLICATE_GROUP_NAME: 'Doppelter Benutzergruppenname', + EMAIL_MESSAGE_NOT_FOUND: 'Email wurde nicht gefunden', + EMAIL_RECIPIENT_NOT_FOUND: 'E-Mail-Empfänger nicht gefunden', + EMPTY_VARIABLES_ARRAY: 'Leeres variables Array', + ENERGY_CATEGORY_NOT_FOUND: 'Energieklassifizierung nicht gefunden', + ENERGY_ITEM_NOT_FOUND: 'Kein Energieverbrauchselement gefunden', + COMBINED_EQUIPMENT_METER_RELATIONSHIP_EXISTED: 'Die Beziehung zwischen der kombinierten Ausrüstung und dem Zähler besteht bereits', + COMBINED_EQUIPMENT_METER_RELATIONSHIP_NOT_FOUND: 'Die Beziehung zwischen der kombinierten Ausrüstung und dem Messgerät wurde nicht gefunden', + COMBINED_EQUIPMENT_NOT_FOUND: 'Kombinationsgerät nicht gefunden', + COMBINED_EQUIPMENT_OFFLINE_METER_RELATIONSHIP_NOT_FOUND: 'Die Beziehung zwischen dem kombinierten Gerät und der Offline-Tabelle wurde nicht gefunden', + COMBINED_EQUIPMENT_OFFLINE_METER_RELATIONSHIP_ALREADY_EXISTS: 'Die Beziehung zwischen dem kombinierten Gerät und der Offline-Tabelle besteht bereits', + COMBINED_EQUIPMENT_VIRTUAL_METER_RELATIONSHIP_NOT_FOUND: 'Die Beziehung zwischen dem kombinierten Gerät und der virtuellen Tabelle wurde nicht gefunden', + COMBINED_EQUIPMENT_VIRTUAL_METER_RELATIONSHIP_ALREADY_EXISTS: 'Die Beziehung zwischen dem kombinierten Gerät und der virtuellen Tabelle besteht bereits', + EQUIPMENT_METER_RELATIONSHIP_EXISTED: 'Die Beziehung zwischen Gerät und Zähler besteht bereits', + EQUIPMENT_METER_RELATIONSHIP_NOT_FOUND: 'Geräte- und Zählerbeziehung nicht gefunden', + EQUIPMENT_NOT_FOUND: 'Gerät nicht gefunden', + EQUIPMENT_OFFLINE_METER_RELATIONSHIP_NOT_FOUND: 'Die Beziehung zwischen dem Gerät und der Offline-Tabelle wurde nicht gefunden', + EQUIPMENT_OFFLINE_METER_RELATIONSHIP_ALREADY_EXISTS: 'Die Beziehung zwischen dem Gerät und der Offline-Tabelle besteht bereits', + EQUIPMENT_VIRTUAL_METER_RELATIONSHIP_NOT_FOUND: 'Die Beziehung zwischen dem Gerät und der virtuellen Tabelle wurde nicht gefunden', + EQUIPMENT_VIRTUAL_METER_RELATIONSHIP_ALREADY_EXISTS: 'Die Beziehung zwischen dem Gerät und der virtuellen Tabelle besteht bereits', + SPACE_NOT_FOUND: 'Kein Platz gefunden', + SPACE_ALREADY_ASSOCIATED_WITH_METER: 'Der Raum ist bereits dem Zähler zugeordnet', + SPACE_ALREADY_ASSOCIATED_WITH_OFFLINE_METER: 'Der Speicherplatz ist bereits der Offline-Tabelle zugeordnet', + SPACE_ALREADY_ASSOCIATED_WITH_VIRTUAL_METER: 'Der Speicherplatz ist bereits der virtuellen Tabelle zugeordnet', + SPACE_AND_METER_RELATIONSHIP_NOT_FOUND: 'Die Beziehung zwischen dem Raum und dem Zähler wurde nicht gefunden', + SPACE_AND_OFFLINE_METER_RELATIONSHIP_NOT_FOUND: 'Speicherplatz und Offline-Tabellenbeziehung nicht gefunden', + SPACE_AND_VIRTUAL_METER_RELATIONSHIP_NOT_FOUND: 'Speicherplatz und virtuelle Tabellenbeziehung nicht gefunden', + GSM_CONFIG_NOT_FOUND: 'GSM-Konfiguration nicht gefunden', + GROUP_NOT_FOUND: 'Benutzergruppe nicht gefunden', + KNOWLEDGE_FILE_NOT_FOUND: 'Wissensdatei nicht gefunden', + INVALID_: 'ungültig', + INVALID_TENANT_ID: 'Ungültige Mieter-ID', + INVALID_STORE_ID: 'Ungültige Geschäfts-ID', + INVALID_ADVANCE_REPORT_FILE_ID: 'Ungültige ID der erweiterten Berichtsdatei', + INVALID_AREA_VALUE: 'Ungültiger Flächenwert', + INVALID_COST_CENTER_ID: 'Ungültige Kostenstellen-ID', + INVALID_DATA_SOURCE_ID: 'Ungültige Datenquellen-ID', + INVALID_DATA_SOURCE_NAME: 'Ungültiger Datenquellenname', + INVALID_DATA_SOURCE_PROTOCOL: 'Ungültiges Datenquellenprotokoll.', + INVALID_DATE: 'Ungültiges Datum (voraussichtliches Format: JJJJ-MM-TT)', + INVALID_DATETIME_DATA: 'Ungültige Datums- und Uhrzeitdaten', + INVALID_EMAIL_MESSAGE_ID: 'Ungültige E-Mail-ID', + INVALID_EMAIL_RECIPIENT_ID: 'Ungültige E-Mail-Empfänger-ID', + INVALID_ENERGY_CATEGORY_ID: 'Ungültige Energieklassifizierungs-ID', + INVALID_ENERGY_ITEM_ID: 'Ungültige Energieverbrauchs-Artikel-ID', + INVALID_COMBINED_EQUIPMENT_ID: 'Ungültige Geräte-ID', + INVALID_EQUIPMENT_ID: 'Ungültige Geräte-ID', + INVALID_SPACE_ID: 'Ungültige Leerzeichen-ID', + INVALID_GSM_CONFIG_ID: 'Ungültige GSM-Konfigurations-ID', + INVALID_GROUP_ID: 'Ungültige Benutzergruppen-ID', + INVALID_KNOWLEDGE_FILE_ID: 'Ungültige ID der Wissensdatei', + INVALID_ID: 'Ungültige ID', + INVALID_MESSAGE_ID: 'Ungültige Nachrichten ID', + INVALID_METER_ID: 'Ungültige Zähler-ID', + INVALID_METER_UUID: 'Ungültige UUID des Messgeräts', + INVALID_OFFLINE_COST_FILE_ID: 'Ungültige Offline-Kostendatei-ID', + INVALID_OFFLINE_METER_FILE__ID: 'Ungültige Offline-Tabellendatei-ID', + INVALID_OFFLINE_METER_FILE_ID: 'Ungültige Offline-Tabellendatei-ID', + INVALID_OFFLINE_METER_ID: 'Ungültige Offline-Tabellen-ID', + INVALID_PASSWORD: 'Ungültiges Passwort', + INVALID_POINT_ID: 'Ungültige Punkt-ID', + INVALID_PRIVILEGE_ID_: 'Ungültige Berechtigungs-ID', + INVALID_PRIVILEGE_ID: 'Ungültige Berechtigungs-ID', + INVALID_PRIVILEGE_TO_RESET_PASSWORD: 'Ungültige Berechtigung zum Zurücksetzen des Kennworts', + INVALID_RULE_ID: 'Ungültige Regel-ID', + INVALID_SMS_RECIPIENT_ID: 'Ungültige SMS-Empfänger-ID', + INVALID_TARIFF_BLOCK_PRICING: 'Ungültiger Staffelpreis', + INVALID_TARIFF_ID: 'Ungültige Tarif-ID', + INVALID_TARIFF_TIME_OF_USE_PRICING: 'Ungültiger Timesharing-Preis', + INVALID_TARIFF_TYPE: 'Ungültiger Kurstyp', + INVALID_TIMEZONE_ID: 'Ungültige Zeitzonen-ID', + INVALID_USER_ID: 'Ungültige Benutzer-Id', + INVALID_USER_NAME: 'Ungültiger Benutzername', + INVALID_VIRTUAL_METER_ID: 'Ungültige ID der virtuellen Tabelle', + INVALID_VIRTUAL_METER_NAME: 'Ungültiger Name der virtuellen Tabelle', + INVALID_WEB_MESSAGE_ID: 'Ungültige Seiteninformations-ID', + INVALID_COOKIES_PLEASE_RE_LOGIN: 'Ungültiger Cookie, bitte erneut anmelden', + INVALID_EMAIL: 'Ungültige E-Mail', + INVALID_EMS_CONTACT_EMAIL_VALUE: 'Ungültiger Wert für ems_contact_email', + INVALID_EMS_CONTACT_NAME_VALUE: 'Ungültiger Wert für ems_contact_name', + INVALID_EMS_CONTACT_PHONE_VALUE: 'Ungültiger Wert für ems_contact_phone', + INVALID_END_DATE_TIME: 'Ungültiges Enddatum (volles erwartetes Format: JJJJ-MM-TTTHH: MM: SS)', + INVALID_END_DATE_TIME_YMD: 'Ungültige Enddatumzeit (erwartetes Format: JJJJ-MM-TTTHH)', + INVALID_END_DATE_TIME_YMDHMS: 'Ungültige Enddatumzeit (erwartetes Format: JJJJ-MM-TTTHH: MM: SS)', + INVALID_EQUATION_IN_EXPRESSION: 'Ungültige Ausdrucksformel', + INVALID_COMBINED_EQUIPMENTS_SHUTDOWN_RATE_VALUE: 'Ungültiger _shutdown_rate-Wert des Geräts', + INVALID_EQUIPMENTS_SHUTDOWN_RATE_VALUE: 'Ungültiger _shutdown_rate-Wert des Geräts', + INVALID_EXPRESSION_OBJECT: 'Ungültiges Ausdrucksobjekt', + INVALID_EXTERNAL_ID_VALUE: 'Ungültige externe ID', + INVALID_IDLING_VALUE: 'Ungültiger Trockenlaufwert', + INVALID_IS_COUNTED_VALUE: 'Ungültiger is_counted-Wert', + INVALID_IS_COMBINED_EQUIPMENT_STATUS_COUNTED_VALUE: 'Ungültiger Wert für is_equipment_status_counted', + INVALID_IS_EQUIPMENT_STATUS_COUNTED_VALUE: 'Ungültiger Wert für is_equipment_status_counted', + INVALID_IS_MAIN_VALUE: 'Ungültiger is_main-Wert', + INVALID_IS_OUTPUT_VALUE: 'Ungültiger is_output-Wert', + INVALID_IS_OUTPUT_COUNTED_VALUE: 'Ungültiger is_output_counted-Wert', + INVALID_IS_PRODUCT_COUNTED_VALUE: 'Ungültiger is_product_counted-Wert', + INVALID_MAINTAINER_VALUE: 'Ungültiger Wartungsquotient', + INVALID_MAINTENANCE_VALUE: 'Ungültiger Wartungswert', + INVALID_MANUFACTURER_VALUE: 'Ungültiger Herstellerwert', + INVALID_PERIOD: 'Ungültiger Zeitraum', + INVALID_PERIOD_FORMAT: 'Ungültiges Zeitraumformat (erwartetes Format \'year\', \'month\', \'day\' or \'hour\')', + INVALID_PRIVILEGES_VALUE: 'Ungültiger Zeitraum', + INVALID_PRODUCTID_ID: 'Ungültige Produkt-ID', + INVALID_REPAIR_VALUE: 'Ungültiger Reparaturwert', + INVALID_RUNNING_VALUE: 'Ungültiger Betriebswert', + INVALID_SERIAL_NUMBER_VALUE: 'Ungültiger Wert für serial_number', + INVALID_START_DATE_TIME: 'Ungültige Startzeit (vollständiges erwartetes Format: JJJJ-MM-TTTHH: MM: SS)', + INVALID_START_DATE_TIME_YMD: 'Ungültige Startzeit (erwartetes Format: JJJJ-MM-TT)', + INVALID_START_DATE_TIME_YMDHMS: 'Ungültige Startzeit (erwartetes Format: JJJJ-MM-TTTHH: MM: SS)', + INVALID_SUSPENDED_VALUE: 'Ungültiger Pausenwert', + INVALID_USE_LIFE_END_VALUE: 'Ungültiger Wert für die Lebensdauer des Geräts', + INVALID_USE_LIFE_START_VALUE: 'Ungültiger Startwert der Gerätelebensdauer', + INVALID_VARIABLE_METER_ID: 'Ungültige Variable meter_id', + INVALID_VARIABLE_METER_TYPE: 'Ungültige Variable meter_type', + INVALID_VARIABLE_NAME: 'Ungültiger Variablenname', + INVALID_WARNING_VALUE: 'Ungültiger Warnwert', + METER_NOT_FOUND: 'Kein Zähler gefunden', + METER_POINT_RELATIONSHIP_EXISTED: 'Es gibt eine Beziehung zwischen Metern und Punkten', + METER_POINT_RELATIONSHIP_NOT_FOUND: 'Die Beziehung zwischen dem Messgerät und dem Punkt wurde nicht gefunden', + METER_OF_VARIABLE_NOT_FOUND: 'Kein mit der Variablen verknüpftes Messgerät gefunden', + OFFLINE_COST_FILE_NOT_FOUND: 'Offline-Kostendatei nicht gefunden', + OFFLINE_METER_FILE_NOT_FOUND: 'Offline-Tabellendatei nicht gefunden', + OFFLINE_METER_NOT_FOUND: 'Offline-Tabelle nicht gefunden', + OFFLINE_METER_OF_VARIABLE_NOT_FOUND: 'Die der Variablen zugeordnete Offline-Tabelle wurde nicht gefunden', + OUTPUT_OF_PRODUCT_NOT_FOUND: 'Produktausgabe nicht gefunden', + PART_NOT_FOUND: 'Teil nicht gefunden', + PART_SHIFT_NOT_FOUND: 'Teilverschiebung nicht gefunden', + PLEASE_RE_LOGIN: 'Bitte melden Sie sich erneut an', + POINT_NOT_FOUND: 'Datenpunkt nicht gefunden', + PRIVILEGE_NOT_FOUND: 'Berechtigung nicht gefunden', + RULE_NOT_FOUND: 'Regel nicht gefunden', + SMS_RECIPIENT_NOT_FOUND: 'SMS-Empfänger nicht gefunden', + START_DATE_SHOULD_BE_EARLY_THAN_END_DATE: 'Das Startdatum sollte vor dem Enddatum liegen', + START_DATETIME_SHOULD_BE_EARLY_THAN_END_DATETIME: 'Das Startdatum und die Startzeit sollten vor dem Enddatum und der Endzeit liegen', + TARIFF_IN_USE: 'Rate wird verwendet', + TARIFF_NOT_EMPTY: 'Die Rate ist nicht leer', + TARIFF_NOT_FOUND: 'Rate nicht gefunden', + TARIFF_ALREADY_ASSOCIATED_WITH_COSTCENTER: 'Der Tarif ist bereits der Kostenstelle zugeordnet', + TARIFF_ALREADY_ASSOCIATED_WITH_SPACE: 'Die Rate wurde mit dem Speicherplatz verknüpft', + TARIFF_IS_NOT_ASSOCIATED_WITH_COST_CENTER: 'Der Tarif ist nicht mit der Kostenstelle verknüpft', + TARIFF_IS_NOT_ASSOCIATED_WITH_SPACE: 'Rate und Platz sind nicht miteinander verbunden', + POINT_ALREADY_ASSOCIATED_WITH_SPACE: 'Datenpunkte wurden mit dem Raum verknüpft', + POINT_IS_NOT_ASSOCIATED_WITH_SPACE: 'Datenpunkte sind nicht mit Leerzeichen verknüpft', + TEAM_NOT_FOUND: 'Kein Team gefunden', + TEXT_MESSAGE_NOT_FOUND: 'SMS nicht gefunden', + THERE_IS_RELATIONSHIP_WITH_TENANTS: 'Haben Sie eine Beziehung mit dem Mieter', + THERE_IS_RELATIONSHIP_WITH_STORES: 'Hat eine Beziehung zum Geschäft', + THERE_IS_RELATIONSHIP_WITH_COMPANIES: 'Haben Sie eine Beziehung mit dem Unternehmen', + THERE_IS_RELATIONSHIP_WITH_COMBINED_EQUIPMENTS: 'Bezogen auf kombinierte Ausrüstung', + THERE_IS_RELATIONSHIP_WITH_EQUIPMENTS: 'Bezogen auf Ausrüstung', + THERE_IS_RELATIONSHIP_WITH_SPACES: 'Hat eine Beziehung zum Raum', + THERE_IS_RELATIONSHIP_WITH_METERS: 'Bezogen auf Meter', + THERE_IS_RELATIONSHIP_WITH_OFFLINE_METERS: 'Bezogen auf Offline-Tabelle', + THERE_IS_RELATIONSHIP_WITH_TEAMS: 'Habe eine Beziehung zum Team', + THERE_IS_RELATIONSHIP_WITH_USERS: 'Haben Sie eine Beziehung zu Benutzern', + THERE_IS_RELATIONSHIP_WITH_VIRTUAL_METERS: 'Bezogen auf virtuelle Tabelle', + TIMEZONE_NOT_FOUND: 'Zeitzone nicht gefunden', + USER_NOT_FOUND: 'Benutzer wurde nicht gefunden', + USER_SESSION_TIMEOUT: 'Zeitlimit für Benutzersitzung', + USER_ALREADY_IN_THE_GROUP: 'Der Benutzer ist bereits in der Benutzergruppe', + USER_IS_NOT_IN_THE_GROUP: 'Benutzer ist nicht in Benutzergruppe', + USER_SESSION_NOT_FOUND: 'Benutzersitzung nicht gefunden', + VIRTUAL_METER_NAME_ALREADY_EXISTS: 'Der Name der virtuellen Tabelle ist bereits vorhanden', + VIRTUAL_METER_NOT_FOUND: 'Virtuelle Tabelle nicht gefunden', + VIRTUAL_METER_OF_VARIABLE_NOT_FOUND: 'Virtuelle Tabelle für Variable nicht gefunden', + WEB_MESSAGE_NOT_FOUND: 'Webseiteninformationen nicht gefunden', + YOU_DO_NOT_HAVE_PERMISSION_TO_VIEW_THE_DATA: 'Sie haben keine Berechtigung zum Anzeigen von Daten.', + + }, + }) ; var lang = window.localStorage.getItem("language") || "cn"; From f3b62c91a759d5d37ea694117c52661f28fb8245 Mon Sep 17 00:00:00 2001 From: "13621160019@163.com" <13621160019@163.com> Date: Thu, 11 Mar 2021 15:26:18 +0800 Subject: [PATCH 2/2] added excel exporter of combinedequipmentstatistics report --- .../excelexporters/combinedequipmentload.py | 101 ++--- .../combinedequipmentstatistics.py | 414 ++++++++++++++++++ .../excelexporters/equipmentstatistics.py | 99 ++--- myems-api/excelexporters/shopfloorload.py | 137 +++--- .../excelexporters/shopfloorstatistics.py | 172 ++++---- myems-api/excelexporters/spacestatistics.py | 173 ++++---- .../reports/combinedequipmentstatistics.py | 8 + 7 files changed, 756 insertions(+), 348 deletions(-) create mode 100644 myems-api/excelexporters/combinedequipmentstatistics.py diff --git a/myems-api/excelexporters/combinedequipmentload.py b/myems-api/excelexporters/combinedequipmentload.py index f7908202..f9845590 100644 --- a/myems-api/excelexporters/combinedequipmentload.py +++ b/myems-api/excelexporters/combinedequipmentload.py @@ -113,12 +113,6 @@ def generate_excel(report, wrap_text=False, shrink_to_fit=False, indent=0) - # c_r_alignment = Alignment(vertical='bottom', - # horizontal='center', - # text_rotation=0, - # wrap_text=False, - # shrink_to_fit=False, - # indent=0) # Img img = Image("excelexporters/myems.png") @@ -262,9 +256,9 @@ def generate_excel(report, ######################################################## # Third: 详细数据 - # row_sat~ row_sat + 6*cal_len: line - # row_da: table title - # row_da + 1~: table_data + # analysis_end_row_number~ analysis_end_row_number + 6*cal_len: line + # detailed_start_row_number: table title + # detailed_start_row_number + 1~: table_data ######################################################## has_timestamps_flag = True if "timestamps" not in reporting_period_data.keys() or \ @@ -277,40 +271,37 @@ def generate_excel(report, names = reporting_period_data['names'] ca_len = len(names) time_len = len(timestamps) - # row_lines == the number of rows of lines - row_lines = 6 * ca_len - # row_sat == the number of rows of statistical analysis table - row_sat = 9 + 2 * ca_len - # row_da == the number of rows of Detailed data - row_da = row_sat + row_lines + 1 + line_charts_row_number = 6 * ca_len + analysis_end_row_number = 9 + 2 * ca_len + detailed_start_row_number = analysis_end_row_number + line_charts_row_number + 1 - ws['B' + str(row_da)].font = title_font - ws['B' + str(row_da)] = name + ' 详细数据' + ws['B' + str(detailed_start_row_number)].font = title_font + ws['B' + str(detailed_start_row_number)] = name + ' 详细数据' # table_title - ws['B' + str(row_da + 1)].fill = table_fill - ws['B' + str(row_da + 1)].font = name_font - ws['B' + str(row_da + 1)].alignment = c_c_alignment - ws['B' + str(row_da + 1)] = "日期时间" - ws['B' + str(row_da + 1)].border = f_border + ws['B' + str(detailed_start_row_number + 1)].fill = table_fill + ws['B' + str(detailed_start_row_number + 1)].font = name_font + ws['B' + str(detailed_start_row_number + 1)].alignment = c_c_alignment + ws['B' + str(detailed_start_row_number + 1)] = "日期时间" + ws['B' + str(detailed_start_row_number + 1)].border = f_border for i in range(0, ca_len): col_average = chr(ord('C') + 2 * i) col_maximum = chr(ord('D') + 2 * i) - ws[col_average + str(row_da + 1)].font = name_font - ws[col_average + str(row_da + 1)].alignment = c_c_alignment - ws[col_average + str(row_da + 1)] = names[i] + " 平均负荷(" + reporting_period_data['units'][ + ws[col_average + str(detailed_start_row_number + 1)].font = name_font + ws[col_average + str(detailed_start_row_number + 1)].alignment = c_c_alignment + ws[col_average + str(detailed_start_row_number + 1)] = names[i] + " 平均负荷(" + reporting_period_data['units'][ i] + "/H)" - ws[col_average + str(row_da + 1)].border = f_border + ws[col_average + str(detailed_start_row_number + 1)].border = f_border - ws[col_maximum + str(row_da + 1)].font = name_font - ws[col_maximum + str(row_da + 1)].alignment = c_c_alignment - ws[col_maximum + str(row_da + 1)] = names[i] + " 最大负荷(" + reporting_period_data['units'][ + ws[col_maximum + str(detailed_start_row_number + 1)].font = name_font + ws[col_maximum + str(detailed_start_row_number + 1)].alignment = c_c_alignment + ws[col_maximum + str(detailed_start_row_number + 1)] = names[i] + " 最大负荷(" + reporting_period_data['units'][ i] + "/H)" - ws[col_maximum + str(row_da + 1)].border = f_border + ws[col_maximum + str(detailed_start_row_number + 1)].border = f_border # table_date for i in range(0, time_len): - rows = i + row_da + 2 + rows = i + detailed_start_row_number + 2 ws['B' + str(rows)].font = name_font ws['B' + str(rows)].alignment = c_c_alignment @@ -335,32 +326,36 @@ def generate_excel(report, ws[col_maximum + str(rows)].number_format = '0.00' ws[col_maximum + str(rows)].border = f_border - # LineChart + ######################################################## + # third: LineChart + # LineChart requires data from the detailed data table in the Excel file + # so print the detailed data table first and then print LineChart + ######################################################## for i in range(0, ca_len): - lc = LineChart() - lc.title = "报告期 最大负荷" - lc.style = 10 - lc.x_axis.majorTickMark = 'in' - lc.y_axis.majorTickMark = 'in' - lc.smooth = True - lc.x_axis.crosses = 'min' - lc.height = 8.25 - lc.width = 24 - lc.dLbls = DataLabelList() - lc.dLbls.dLblPos = 't' - lc.dLbls.showVal = True - times = Reference(ws, min_col=2, min_row=row_da + 2, - max_row=row_da + 2 + time_len) - lc_data = Reference(ws, min_col=2 + 2 * (i+1), min_row=row_da + 1, - max_row=row_da + 1 + time_len) - lc.add_data(lc_data, titles_from_data=True) - lc.set_categories(times) - ser = lc.series[0] + line = LineChart() + line.title = "报告期 最大负荷 - " + names[i] + "(" + reporting_period_data['units'][i] + ")" + line.style = 10 + line.x_axis.majorTickMark = 'in' + line.y_axis.majorTickMark = 'in' + line.smooth = True + line.x_axis.crosses = 'min' + line.height = 8.25 + line.width = 24 + line.dLbls = DataLabelList() + line.dLbls.dLblPos = 't' + line.dLbls.showVal = True + times = Reference(ws, min_col=2, min_row=detailed_start_row_number + 2, + max_row=detailed_start_row_number + 2 + time_len) + line_data = Reference(ws, min_col=2 + 2 * (i + 1), min_row=detailed_start_row_number + 1, + max_row=detailed_start_row_number + 1 + time_len) + line.add_data(line_data, titles_from_data=True) + line.set_categories(times) + ser = line.series[0] ser.marker.symbol = "diamond" ser.marker.size = 5 chart_col = 'B' - chart_cell = str(row_sat + 6 * i) - ws.add_chart(lc, chart_col + chart_cell) + chart_cell = str(analysis_end_row_number + 6 * i) + ws.add_chart(line, chart_col + chart_cell) filename = str(uuid.uuid4()) + '.xlsx' wb.save(filename) diff --git a/myems-api/excelexporters/combinedequipmentstatistics.py b/myems-api/excelexporters/combinedequipmentstatistics.py new file mode 100644 index 00000000..cbef99ea --- /dev/null +++ b/myems-api/excelexporters/combinedequipmentstatistics.py @@ -0,0 +1,414 @@ +import base64 +import uuid +import os +from openpyxl.chart import ( + LineChart, + Reference, +) +from openpyxl.chart.label import DataLabelList +from openpyxl.styles import PatternFill, Border, Side, Alignment, Font +from openpyxl.drawing.image import Image +from openpyxl import Workbook + + +#################################################################################################################### +# PROCEDURES +# Step 1: Validate the report data +# Step 2: Generate excel file +# Step 3: Encode the excel file bytes to Base64 +#################################################################################################################### + + +def export(report, + name, + reporting_start_datetime_local, + reporting_end_datetime_local, + period_type): + #################################################################################################################### + # Step 1: Validate the report data + #################################################################################################################### + if report is None: + return None + print(report) + + #################################################################################################################### + # Step 2: Generate excel file from the report data + #################################################################################################################### + filename = generate_excel(report, + name, + reporting_start_datetime_local, + reporting_end_datetime_local, + period_type) + #################################################################################################################### + # Step 3: Encode the excel file to Base64 + #################################################################################################################### + try: + with open(filename, 'rb') as binary_file: + binary_file_data = binary_file.read() + except IOError as ex: + pass + + # Base64 encode the bytes + base64_encoded_data = base64.b64encode(binary_file_data) + # get the Base64 encoded data using human-readable characters. + base64_message = base64_encoded_data.decode('utf-8') + # delete the file from server + try: + os.remove(filename) + except NotImplementedError as ex: + pass + return base64_message + + +def generate_excel(report, + name, + reporting_start_datetime_local, + reporting_end_datetime_local, + period_type): + wb = Workbook() + ws = wb.active + + # Row height + ws.row_dimensions[1].height = 102 + + for i in range(2, 2000 + 1): + ws.row_dimensions[i].height = 42 + + # Col width + ws.column_dimensions['A'].width = 1.5 + ws.column_dimensions['B'].width = 25.0 + + for i in range(ord('C'), ord('L')): + ws.column_dimensions[chr(i)].width = 15.0 + + # Font + name_font = Font(name='Constantia', size=15, bold=True) + title_font = Font(name='宋体', size=15, bold=True) + # data_font = Font(name='Franklin Gothic Book', size=11) + + table_fill = PatternFill(fill_type='solid', fgColor='1F497D') + f_border = Border(left=Side(border_style='medium', color='00000000'), + right=Side(border_style='medium', color='00000000'), + bottom=Side(border_style='medium', color='00000000'), + top=Side(border_style='medium', color='00000000') + ) + b_border = Border( + bottom=Side(border_style='medium', color='00000000'), + ) + + b_c_alignment = Alignment(vertical='bottom', + horizontal='center', + text_rotation=0, + wrap_text=False, + shrink_to_fit=False, + indent=0) + c_c_alignment = Alignment(vertical='center', + horizontal='center', + text_rotation=0, + wrap_text=False, + shrink_to_fit=False, + indent=0) + b_r_alignment = Alignment(vertical='bottom', + horizontal='right', + text_rotation=0, + wrap_text=False, + shrink_to_fit=False, + indent=0) + + # Img + img = Image("excelexporters/myems.png") + # img = Image("myems.png") + img.width = img.width * 0.85 + img.height = img.height * 0.85 + ws.add_image(img, 'B1') + + # Title + ws['B3'].font = name_font + ws['B3'].alignment = b_r_alignment + ws['B3'] = 'Name:' + ws['C3'].border = b_border + ws['C3'].alignment = b_c_alignment + ws['C3'].font = name_font + ws['C3'] = name + + ws['D3'].font = name_font + ws['D3'].alignment = b_r_alignment + ws['D3'] = 'Period:' + ws['E3'].border = b_border + ws['E3'].alignment = b_c_alignment + ws['E3'].font = name_font + ws['E3'] = period_type + + ws['F3'].font = name_font + ws['F3'].alignment = b_r_alignment + ws['F3'] = 'Date:' + ws['G3'].border = b_border + ws['G3'].alignment = b_c_alignment + ws['G3'].font = name_font + ws['G3'] = reporting_start_datetime_local + "__" + reporting_end_datetime_local + ws.merge_cells("G3:H3") + + if "reporting_period" not in report.keys() or \ + "names" not in report['reporting_period'].keys() or len(report['reporting_period']['names']) == 0: + filename = str(uuid.uuid4()) + '.xlsx' + wb.save(filename) + + return filename + ################################################# + # First: 统计分析 + # 6: title + # 7: table title + # 8~ca_len table_data + ################################################# + reporting_period_data = report['reporting_period'] + + has_energy_data_flag = True + + if "names" not in reporting_period_data.keys() or \ + reporting_period_data['names'] is None or \ + len(reporting_period_data['names']) == 0: + has_energy_data_flag = False + + filename = str(uuid.uuid4()) + '.xlsx' + wb.save(filename) + + return filename + + if has_energy_data_flag: + ws['B6'].font = title_font + ws['B6'] = name + ' 统计分析' + + category = reporting_period_data['names'] + + # table_title + ws['B7'].fill = table_fill + ws['B7'].font = title_font + ws['B7'].alignment = c_c_alignment + ws['B7'] = '报告期' + ws['B7'].border = f_border + + ws['C7'].font = title_font + ws['C7'].alignment = c_c_alignment + ws['C7'] = '算术平均数' + ws['C7'].border = f_border + + ws['D7'].font = title_font + ws['D7'].alignment = c_c_alignment + ws['D7'] = '中位数' + ws['D7'].border = f_border + + ws['E7'].font = title_font + ws['E7'].alignment = c_c_alignment + ws['E7'] = '最小值' + ws['E7'].border = f_border + + ws['F7'].font = title_font + ws['F7'].alignment = c_c_alignment + ws['F7'] = '最大值' + ws['F7'].border = f_border + + ws['G7'].font = title_font + ws['G7'].alignment = c_c_alignment + ws['G7'] = '样本标准差' + ws['G7'].border = f_border + + ws['H7'].font = title_font + ws['H7'].alignment = c_c_alignment + ws['H7'] = '样本方差' + ws['H7'].border = f_border + + # table_data + + for i, value in enumerate(category): + row = i * 2 + 8 + ws['B' + str(row)].font = name_font + ws['B' + str(row)].alignment = c_c_alignment + ws['B' + str(row)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][i] + " )" + ws['B' + str(row)].border = f_border + + ws['B' + str(row + 1)].font = name_font + ws['B' + str(row + 1)].alignment = c_c_alignment + ws['B' + str(row + 1)] = "环比" + ws['B' + str(row + 1)].border = f_border + + ws['C' + str(row)].font = name_font + ws['C' + str(row)].alignment = c_c_alignment + ws['C' + str(row)] = reporting_period_data['means'][i] \ + if reporting_period_data['means'][i] is not None else '' + ws['C' + str(row)].border = f_border + ws['C' + str(row)].number_format = '0.00' + + ws['C' + str(row + 1)].font = name_font + ws['C' + str(row + 1)].alignment = c_c_alignment + ws['C' + str(row + 1)] = str(round(reporting_period_data['means_increment_rate'][i] * 100, 2)) + "%" \ + if reporting_period_data['means_increment_rate'][i] is not None else '0.00%' + ws['C' + str(row + 1)].border = f_border + + ws['D' + str(row)].font = name_font + ws['D' + str(row)].alignment = c_c_alignment + ws['D' + str(row)] = reporting_period_data['medians'][i] \ + if reporting_period_data['medians'][i] is not None else '' + ws['D' + str(row)].border = f_border + ws['D' + str(row)].number_format = '0.00' + + ws['D' + str(row + 1)].font = name_font + ws['D' + str(row + 1)].alignment = c_c_alignment + ws['D' + str(row + 1)] = str(round(reporting_period_data['medians_increment_rate'][i] * 100, 2)) + "%" \ + if reporting_period_data['medians_increment_rate'][i] is not None else '0.00%' + ws['D' + str(row + 1)].border = f_border + + ws['E' + str(row)].font = name_font + ws['E' + str(row)].alignment = c_c_alignment + ws['E' + str(row)] = reporting_period_data['minimums'][i] \ + if reporting_period_data['minimums'][i] is not None else '' + ws['E' + str(row)].border = f_border + ws['E' + str(row)].number_format = '0.00' + + ws['E' + str(row + 1)].font = name_font + ws['E' + str(row + 1)].alignment = c_c_alignment + ws['E' + str(row + 1)] = str(round(reporting_period_data['minimums_increment_rate'][i] * 100, 2)) + "%" \ + if reporting_period_data['minimums_increment_rate'][i] is not None else '0.00%' + ws['E' + str(row + 1)].border = f_border + + ws['F' + str(row)].font = name_font + ws['F' + str(row)].alignment = c_c_alignment + ws['F' + str(row)] = reporting_period_data['maximums'][i] \ + if reporting_period_data['maximums'][i] is not None else '' + ws['F' + str(row)].border = f_border + ws['F' + str(row)].number_format = '0.00' + + ws['F' + str(row + 1)].font = name_font + ws['F' + str(row + 1)].alignment = c_c_alignment + ws['F' + str(row + 1)] = str(round(reporting_period_data['maximums_increment_rate'][i] * 100, 2)) + "%" \ + if reporting_period_data['maximums_increment_rate'][i] is not None else '0.00%' + ws['F' + str(row + 1)].border = f_border + + ws['G' + str(row)].font = name_font + ws['G' + str(row)].alignment = c_c_alignment + ws['G' + str(row)] = reporting_period_data['stdevs'][i] \ + if reporting_period_data['stdevs'][i] is not None else '' + ws['G' + str(row)].border = f_border + ws['G' + str(row)].number_format = '0.00' + + ws['G' + str(row + 1)].font = name_font + ws['G' + str(row + 1)].alignment = c_c_alignment + ws['G' + str(row + 1)] = str(round(reporting_period_data['stdevs_increment_rate'][i] * 100, 2)) + "%" \ + if reporting_period_data['stdevs_increment_rate'][i] is not None else '0.00%' + ws['G' + str(row + 1)].border = f_border + + ws['H' + str(row)].font = name_font + ws['H' + str(row)].alignment = c_c_alignment + ws['H' + str(row)] = reporting_period_data['variances'][i] \ + if reporting_period_data['variances'][i] is not None else '' + ws['H' + str(row)].border = f_border + ws['H' + str(row)].number_format = '0.00' + + ws['H' + str(row + 1)].font = name_font + ws['H' + str(row + 1)].alignment = c_c_alignment + ws['H' + str(row + 1)] = str(round(reporting_period_data['variances_increment_rate'][i] * 100, 2)) + "%" \ + if reporting_period_data['variances_increment_rate'][i] is not None else '0.00%' + ws['H' + str(row + 1)].border = f_border + + ######################################################## + # Second: 详细数据 + # analysis_end_row_number+1~ analysis_end_row_number+1+line_charts_row_number+: line + # detailed_start_row_number~ : the detailed data table + ######################################################## + has_timestamps_flag = True + if "timestamps" not in reporting_period_data.keys() or \ + reporting_period_data['timestamps'] is None or \ + len(reporting_period_data['timestamps']) == 0: + has_timestamps_flag = False + + if has_timestamps_flag: + timestamps = reporting_period_data['timestamps'][0] + values = reporting_period_data['values'] + names = reporting_period_data['names'] + ca_len = len(names) + time_len = len(timestamps) + # the detailed title + line_charts_row_number = 6 * ca_len + 1 + analysis_end_row_number = 9 + 2 * ca_len + detailed_start_row_number = analysis_end_row_number + line_charts_row_number + + ws['B' + str(detailed_start_row_number)].font = title_font + ws['B' + str(detailed_start_row_number)] = name + ' 详细数据' + # the detailed table_title + ws['B' + str(detailed_start_row_number + 1)].fill = table_fill + ws['B' + str(detailed_start_row_number + 1)].font = name_font + ws['B' + str(detailed_start_row_number + 1)].alignment = c_c_alignment + ws['B' + str(detailed_start_row_number + 1)] = "时间" + ws['B' + str(detailed_start_row_number + 1)].border = f_border + + for i in range(0, ca_len): + col = chr(ord('C') + i) + + ws[col + str(detailed_start_row_number + 1)].font = name_font + ws[col + str(detailed_start_row_number + 1)].alignment = c_c_alignment + ws[col + str(detailed_start_row_number + 1)] = names[i] + " - (" + reporting_period_data['units'][i] + ")" + ws[col + str(detailed_start_row_number + 1)].border = f_border + # the detailed table_date + for i in range(0, time_len): + rows = i + detailed_start_row_number + 2 + + ws['B' + str(rows)].font = name_font + ws['B' + str(rows)].alignment = c_c_alignment + ws['B' + str(rows)] = timestamps[i] + ws['B' + str(rows)].border = f_border + + for index in range(0, ca_len): + col = chr(ord('C') + index) + + ws[col + str(rows)].font = name_font + ws[col + str(rows)].alignment = c_c_alignment + ws[col + str(rows)] = values[index][i] + ws[col + str(rows)].number_format = '0.00' + ws[col + str(rows)].border = f_border + + # 小计 + row_subtotals = detailed_start_row_number + 2 + time_len + ws['B' + str(row_subtotals)].font = name_font + ws['B' + str(row_subtotals)].alignment = c_c_alignment + ws['B' + str(row_subtotals)] = "小计" + ws['B' + str(row_subtotals)].border = f_border + + for i in range(0, ca_len): + col = chr(ord('C') + i) + + ws[col + str(row_subtotals)].font = name_font + ws[col + str(row_subtotals)].alignment = c_c_alignment + ws[col + str(row_subtotals)] = reporting_period_data['subtotals'][i] + ws[col + str(row_subtotals)].border = f_border + ws[col + str(row_subtotals)].number_format = '0.00' + + ######################################################## + # third: LineChart + # LineChart requires data from the detailed data table in the Excel file + # so print the detailed data table first and then print LineChart + ######################################################## + for i in range(0, ca_len): + line = LineChart() + line.title = "报告期消耗" + " - " + names[i] + "(" + reporting_period_data['units'][i] + ")" + line.style = 10 + line.height = 8.40 # cm 1.05*8 1.05cm = 30 pt + line.width = 24 + line.x_axis.majorTickMark = 'in' + line.y_axis.majorTickMark = 'in' + line.dLbls = DataLabelList() + line.dLbls.dLblPos = 't' + line.dLbls.showVal = True + times = Reference(ws, min_col=2, min_row=detailed_start_row_number + 2, + max_row=detailed_start_row_number + 2 + time_len) + line_data = Reference(ws, min_col=3 + i, min_row=detailed_start_row_number + 1, + max_row=detailed_start_row_number + 1 + time_len) + line.add_data(line_data, titles_from_data=True) + line.set_categories(times) + ser = line.series[0] + ser.marker.symbol = "diamond" + ser.marker.size = 5 + ws.add_chart(line, 'B' + str(analysis_end_row_number + 6 * i)) + + filename = str(uuid.uuid4()) + '.xlsx' + wb.save(filename) + + return filename diff --git a/myems-api/excelexporters/equipmentstatistics.py b/myems-api/excelexporters/equipmentstatistics.py index cc42f20d..cbbd737e 100644 --- a/myems-api/excelexporters/equipmentstatistics.py +++ b/myems-api/excelexporters/equipmentstatistics.py @@ -5,6 +5,7 @@ from openpyxl.chart import ( LineChart, Reference, ) +from openpyxl.chart.label import DataLabelList from openpyxl.styles import PatternFill, Border, Side, Alignment, Font from openpyxl.drawing.image import Image from openpyxl import Workbook @@ -68,19 +69,16 @@ def generate_excel(report, ws = wb.active # Row height - ws.row_dimensions[1].height = 121 + ws.row_dimensions[1].height = 102 - for i in range(2, 37 + 1): - ws.row_dimensions[i].height = 30 - - for i in range(38, 90 + 1): - ws.row_dimensions[i].height = 30 + for i in range(2, 2000 + 1): + ws.row_dimensions[i].height = 42 # Col width ws.column_dimensions['A'].width = 1.5 - ws.column_dimensions['B'].width = 20.0 + ws.column_dimensions['B'].width = 25.0 - for i in range(ord('C'), ord('I')): + for i in range(ord('C'), ord('L')): ws.column_dimensions[chr(i)].width = 15.0 # Font @@ -116,12 +114,6 @@ def generate_excel(report, wrap_text=False, shrink_to_fit=False, indent=0) - # c_r_alignment = Alignment(vertical='bottom', - # horizontal='center', - # text_rotation=0, - # wrap_text=False, - # shrink_to_fit=False, - # indent=0) # Img img = Image("excelexporters/myems.png") @@ -317,11 +309,8 @@ def generate_excel(report, ######################################################## # Second: 详细数据 - # row_sat+1~ row_sat+1+row_lines+: line - # row_ddt~ : the detailed data table - # row_sat : the number of rows of the analysis table - # row_lines : the number of rows of all line charts - # row_ddt : The number of rows in which the detailed data table header resides + # a+1~ analysis_end_row_number+1+line_charts_row_number+: line + # detailed_start_row_number~ : the detailed data table ######################################################## has_timestamps_flag = True if "timestamps" not in reporting_period_data.keys() or \ @@ -336,29 +325,29 @@ def generate_excel(report, ca_len = len(names) time_len = len(timestamps) # the detailed title - row_lines = 9 * ca_len - row_sat = 7 + 2 * ca_len - row_ddt = row_sat + row_lines + 2 + line_charts_row_number = 6 * ca_len + 1 + analysis_end_row_number = 7 + 2 * ca_len + detailed_start_row_number = analysis_end_row_number + line_charts_row_number + 2 - ws['B' + str(row_ddt)].font = title_font - ws['B' + str(row_ddt)] = name + ' 详细数据' + ws['B' + str(detailed_start_row_number)].font = title_font + ws['B' + str(detailed_start_row_number)] = name + ' 详细数据' # the detailed table_title - ws['B' + str(row_ddt+1)].fill = table_fill - ws['B' + str(row_ddt+1)].font = name_font - ws['B' + str(row_ddt+1)].alignment = c_c_alignment - ws['B' + str(row_ddt+1)] = "时间" - ws['B' + str(row_ddt+1)].border = f_border + ws['B' + str(detailed_start_row_number + 1)].fill = table_fill + ws['B' + str(detailed_start_row_number + 1)].font = name_font + ws['B' + str(detailed_start_row_number + 1)].alignment = c_c_alignment + ws['B' + str(detailed_start_row_number + 1)] = "时间" + ws['B' + str(detailed_start_row_number + 1)].border = f_border for i in range(0, ca_len): col = chr(ord('C') + i) - ws[col + str(row_ddt+1)].font = name_font - ws[col + str(row_ddt+1)].alignment = c_c_alignment - ws[col + str(row_ddt+1)] = names[i] + " - (" + reporting_period_data['units'][i] + ")" - ws[col + str(row_ddt+1)].border = f_border + ws[col + str(detailed_start_row_number + 1)].font = name_font + ws[col + str(detailed_start_row_number + 1)].alignment = c_c_alignment + ws[col + str(detailed_start_row_number + 1)] = names[i] + " - (" + reporting_period_data['units'][i] + ")" + ws[col + str(detailed_start_row_number + 1)].border = f_border # the detailed table_date for i in range(0, time_len): - rows = i + row_ddt + 2 + rows = i + detailed_start_row_number + 2 ws['B' + str(rows)].font = name_font ws['B' + str(rows)].alignment = c_c_alignment @@ -375,7 +364,7 @@ def generate_excel(report, ws[col + str(rows)].border = f_border # 小计 - row_subtotals = row_ddt + 2 + time_len + row_subtotals = detailed_start_row_number + 2 + time_len ws['B' + str(row_subtotals)].font = name_font ws['B' + str(row_subtotals)].alignment = c_c_alignment ws['B' + str(row_subtotals)] = "小计" @@ -390,26 +379,32 @@ def generate_excel(report, ws[col + str(row_subtotals)].border = f_border ws[col + str(row_subtotals)].number_format = '0.00' - # LineChart + ######################################################## + # third: LineChart + # LineChart requires data from the detailed data table in the Excel file + # so print the detailed data table first and then print LineChart + ######################################################## for i in range(0, ca_len): - - lc = LineChart() - lc.title = "报告期消耗" + " - " + names[i] + "(" + reporting_period_data['units'][i] + ")" - lc.style = 10 - lc.height = 8.40 # cm 1.05*8 1.05cm = 30 pt - lc.width = 23.28 - lc.x_axis.majorTickMark = 'in' - lc.y_axis.majorTickMark = 'in' - times = Reference(ws, min_col=2, min_row=row_ddt + 2, - max_row=row_ddt + 2 + time_len) - lc_data = Reference(ws, min_col=3 + i, min_row=row_ddt + 1, - max_row=row_ddt + 1 + time_len) - lc.add_data(lc_data, titles_from_data=True) - lc.set_categories(times) - ser = lc.series[0] + line = LineChart() + line.title = "报告期消耗" + " - " + names[i] + "(" + reporting_period_data['units'][i] + ")" + line.style = 10 + line.height = 8.40 # cm 1.05*8 1.05cm = 30 pt + line.width = 24 + line.x_axis.majorTickMark = 'in' + line.y_axis.majorTickMark = 'in' + line.dLbls = DataLabelList() + line.dLbls.dLblPos = 't' + line.dLbls.showVal = True + times = Reference(ws, min_col=2, min_row=detailed_start_row_number + 2, + max_row=detailed_start_row_number + 2 + time_len) + line_data = Reference(ws, min_col=3 + i, min_row=detailed_start_row_number + 1, + max_row=detailed_start_row_number + 1 + time_len) + line.add_data(line_data, titles_from_data=True) + line.set_categories(times) + ser = line.series[0] ser.marker.symbol = "diamond" ser.marker.size = 5 - ws.add_chart(lc, 'B' + str(row_sat + 2 + 9 * i)) + ws.add_chart(line, 'B' + str(analysis_end_row_number + 2 + 6 * i)) filename = str(uuid.uuid4()) + '.xlsx' wb.save(filename) diff --git a/myems-api/excelexporters/shopfloorload.py b/myems-api/excelexporters/shopfloorload.py index 9d8e5d23..8803bd30 100644 --- a/myems-api/excelexporters/shopfloorload.py +++ b/myems-api/excelexporters/shopfloorload.py @@ -113,12 +113,6 @@ def generate_excel(report, wrap_text=False, shrink_to_fit=False, indent=0) - # c_r_alignment = Alignment(vertical='bottom', - # horizontal='center', - # text_rotation=0, - # wrap_text=False, - # shrink_to_fit=False, - # indent=0) # Img img = Image("excelexporters/myems.png") @@ -264,40 +258,40 @@ def generate_excel(report, # Second: 报告期单位面积消耗 # 9 + ca_len * 2: title # 10 + ca_len * 2: table title - # row_title + 2 ~ row_title + 2 + ca_len : table_data + # per_unit_area_start_row_number + 2 ~ per_unit_area_start_row_number + 2 + ca_len : table_data ################################################# if has_energy_data_flag: names = reporting_period_data['names'] ca_len = len(names) - row_title = 9 + ca_len * 2 + per_unit_area_start_row_number = 9 + ca_len * 2 - ws['B' + str(row_title)].font = title_font - ws['B' + str(row_title)] = name + ' 单位面积值' + str(report['shopfloor']['area']) + 'M²' + ws['B' + str(per_unit_area_start_row_number)].font = title_font + ws['B' + str(per_unit_area_start_row_number)] = name + ' 单位面积值' + str(report['shopfloor']['area']) + 'M²' category = reporting_period_data['names'] # table_title - ws['B' + str(row_title + 1)].fill = table_fill - ws['B' + str(row_title + 1)].font = title_font - ws['B' + str(row_title + 1)].alignment = c_c_alignment - ws['B' + str(row_title + 1)] = '报告期' - ws['B' + str(row_title + 1)].border = f_border + ws['B' + str(per_unit_area_start_row_number + 1)].fill = table_fill + ws['B' + str(per_unit_area_start_row_number + 1)].font = title_font + ws['B' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment + ws['B' + str(per_unit_area_start_row_number + 1)] = '报告期' + ws['B' + str(per_unit_area_start_row_number + 1)].border = f_border - ws['C' + str(row_title + 1)].font = title_font - ws['C' + str(row_title + 1)].alignment = c_c_alignment - ws['C' + str(row_title + 1)] = '平均负荷' - ws['C' + str(row_title + 1)].border = f_border + ws['C' + str(per_unit_area_start_row_number + 1)].font = title_font + ws['C' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment + ws['C' + str(per_unit_area_start_row_number + 1)] = '平均负荷' + ws['C' + str(per_unit_area_start_row_number + 1)].border = f_border - ws['D' + str(row_title + 1)].font = title_font - ws['D' + str(row_title + 1)].alignment = c_c_alignment - ws['D' + str(row_title + 1)] = '最大负荷' - ws['D' + str(row_title + 1)].border = f_border + ws['D' + str(per_unit_area_start_row_number + 1)].font = title_font + ws['D' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment + ws['D' + str(per_unit_area_start_row_number + 1)] = '最大负荷' + ws['D' + str(per_unit_area_start_row_number + 1)].border = f_border # table_data for i, value in enumerate(category): - row_data = row_title + 2 + i + row_data = per_unit_area_start_row_number + 2 + i ws['B' + str(row_data)].font = name_font ws['B' + str(row_data)].alignment = c_c_alignment ws['B' + str(row_data)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][ @@ -322,9 +316,9 @@ def generate_excel(report, ######################################################## # Third: 详细数据 - # row_sat~ row_sat + 6*cal_len: line - # row_da: table title - # row_da + 1~: table_data + # analysis_end_row_number~ analysis_end_row_number + 6*cal_len: line + # detailed_start_row_number: table title + # detailed_start_row_number + 1~: table_data ######################################################## has_timestamps_flag = True if "timestamps" not in reporting_period_data.keys() or \ @@ -337,40 +331,37 @@ def generate_excel(report, names = reporting_period_data['names'] ca_len = len(names) time_len = len(timestamps) - # row_lines == the number of rows of lines - row_lines = 6 * ca_len - # row_sat == the number of rows of statistical analysis table - row_sat = 12 + 3 * ca_len - # row_da == the number of rows of Detailed data - row_da = row_sat + row_lines + 1 + line_charts_row_number = 6 * ca_len + analysis_end_row_number = 12 + 3 * ca_len + detailed_start_row_number = analysis_end_row_number + line_charts_row_number + 1 - ws['B' + str(row_da)].font = title_font - ws['B' + str(row_da)] = name + ' 详细数据' + ws['B' + str(detailed_start_row_number)].font = title_font + ws['B' + str(detailed_start_row_number)] = name + ' 详细数据' # table_title - ws['B' + str(row_da + 1)].fill = table_fill - ws['B' + str(row_da + 1)].font = name_font - ws['B' + str(row_da + 1)].alignment = c_c_alignment - ws['B' + str(row_da + 1)] = "日期时间" - ws['B' + str(row_da + 1)].border = f_border + ws['B' + str(detailed_start_row_number + 1)].fill = table_fill + ws['B' + str(detailed_start_row_number + 1)].font = name_font + ws['B' + str(detailed_start_row_number + 1)].alignment = c_c_alignment + ws['B' + str(detailed_start_row_number + 1)] = "日期时间" + ws['B' + str(detailed_start_row_number + 1)].border = f_border for i in range(0, ca_len): col_average = chr(ord('C') + 2 * i) col_maximum = chr(ord('D') + 2 * i) - ws[col_average + str(row_da + 1)].font = name_font - ws[col_average + str(row_da + 1)].alignment = c_c_alignment - ws[col_average + str(row_da + 1)] = names[i] + " 平均负荷(" + reporting_period_data['units'][ + ws[col_average + str(detailed_start_row_number + 1)].font = name_font + ws[col_average + str(detailed_start_row_number + 1)].alignment = c_c_alignment + ws[col_average + str(detailed_start_row_number + 1)] = names[i] + " 平均负荷(" + reporting_period_data['units'][ i] + "/H)" - ws[col_average + str(row_da + 1)].border = f_border + ws[col_average + str(detailed_start_row_number + 1)].border = f_border - ws[col_maximum + str(row_da + 1)].font = name_font - ws[col_maximum + str(row_da + 1)].alignment = c_c_alignment - ws[col_maximum + str(row_da + 1)] = names[i] + " 最大负荷(" + reporting_period_data['units'][ + ws[col_maximum + str(detailed_start_row_number + 1)].font = name_font + ws[col_maximum + str(detailed_start_row_number + 1)].alignment = c_c_alignment + ws[col_maximum + str(detailed_start_row_number + 1)] = names[i] + " 最大负荷(" + reporting_period_data['units'][ i] + "/H)" - ws[col_maximum + str(row_da + 1)].border = f_border + ws[col_maximum + str(detailed_start_row_number + 1)].border = f_border # table_date for i in range(0, time_len): - rows = i + row_da + 2 + rows = i + detailed_start_row_number + 2 ws['B' + str(rows)].font = name_font ws['B' + str(rows)].alignment = c_c_alignment @@ -395,32 +386,36 @@ def generate_excel(report, ws[col_maximum + str(rows)].number_format = '0.00' ws[col_maximum + str(rows)].border = f_border - # LineChart + ######################################################## + # third: LineChart + # LineChart requires data from the detailed data table in the Excel file + # so print the detailed data table first and then print LineChart + ######################################################## for i in range(0, ca_len): - lc = LineChart() - lc.title = "报告期 最大负荷" - lc.style = 10 - lc.x_axis.majorTickMark = 'in' - lc.y_axis.majorTickMark = 'in' - lc.smooth = True - lc.x_axis.crosses = 'min' - lc.height = 8.25 - lc.width = 24 - lc.dLbls = DataLabelList() - lc.dLbls.dLblPos = 't' - lc.dLbls.showVal = True - times = Reference(ws, min_col=2, min_row=row_da + 2, - max_row=row_da + 2 + time_len) - lc_data = Reference(ws, min_col=2 + 2 * (i+1), min_row=row_da + 1, - max_row=row_da + 1 + time_len) - lc.add_data(lc_data, titles_from_data=True) - lc.set_categories(times) - ser = lc.series[0] + line = LineChart() + line.title = "报告期 最大负荷 - " + names[i] + "(" + reporting_period_data['units'][i] + ")" + line.style = 10 + line.x_axis.majorTickMark = 'in' + line.y_axis.majorTickMark = 'in' + line.smooth = True + line.x_axis.crosses = 'min' + line.height = 8.25 + line.width = 24 + line.dLbls = DataLabelList() + line.dLbls.dLblPos = 't' + line.dLbls.showVal = True + times = Reference(ws, min_col=2, min_row=detailed_start_row_number + 2, + max_row=detailed_start_row_number + 2 + time_len) + line_data = Reference(ws, min_col=2 + 2 * (i + 1), min_row=detailed_start_row_number + 1, + max_row=detailed_start_row_number + 1 + time_len) + line.add_data(line_data, titles_from_data=True) + line.set_categories(times) + ser = line.series[0] ser.marker.symbol = "diamond" ser.marker.size = 5 chart_col = 'B' - chart_cell = str(row_sat + 6 * i) - ws.add_chart(lc, chart_col + chart_cell) + chart_cell = str(analysis_end_row_number + 6 * i) + ws.add_chart(line, chart_col + chart_cell) filename = str(uuid.uuid4()) + '.xlsx' wb.save(filename) diff --git a/myems-api/excelexporters/shopfloorstatistics.py b/myems-api/excelexporters/shopfloorstatistics.py index 13bba4e8..522505d3 100644 --- a/myems-api/excelexporters/shopfloorstatistics.py +++ b/myems-api/excelexporters/shopfloorstatistics.py @@ -5,6 +5,7 @@ from openpyxl.chart import ( LineChart, Reference, ) +from openpyxl.chart.label import DataLabelList from openpyxl.styles import PatternFill, Border, Side, Alignment, Font from openpyxl.drawing.image import Image from openpyxl import Workbook @@ -68,19 +69,16 @@ def generate_excel(report, ws = wb.active # Row height - ws.row_dimensions[1].height = 121 + ws.row_dimensions[1].height = 102 - for i in range(2, 37 + 1): - ws.row_dimensions[i].height = 30 - - for i in range(38, 90 + 1): - ws.row_dimensions[i].height = 30 + for i in range(2, 2000 + 1): + ws.row_dimensions[i].height = 42 # Col width ws.column_dimensions['A'].width = 1.5 - ws.column_dimensions['B'].width = 20.0 + ws.column_dimensions['B'].width = 25.0 - for i in range(ord('C'), ord('I')): + for i in range(ord('C'), ord('L')): ws.column_dimensions[chr(i)].width = 15.0 # Font @@ -116,12 +114,6 @@ def generate_excel(report, wrap_text=False, shrink_to_fit=False, indent=0) - # c_r_alignment = Alignment(vertical='bottom', - # horizontal='center', - # text_rotation=0, - # wrap_text=False, - # shrink_to_fit=False, - # indent=0) # Img img = Image("excelexporters/myems.png") @@ -318,63 +310,61 @@ def generate_excel(report, # Second: 报告期消耗 # 9 + ca_len * 2: title # 10 + ca_len * 2: table title - # row_title + 2 ~ row_title + 2 + ca_len : table_data + # per_unit_area_start_row_number + 2 ~ per_unit_area_start_row_number + 2 + ca_len : table_data ################################################# if has_energy_data_flag: names = reporting_period_data['names'] ca_len = len(names) - row_title = 9 + ca_len * 2 + per_unit_area_start_row_number = 9 + ca_len * 2 - ws['B' + str(row_title)].font = title_font - ws['B' + str(row_title)] = name + ' 单位面积值' - ws['D' + str(row_title)].font = title_font - ws['D' + str(row_title)] = str(report['shopfloor']['area']) + 'M²' + ws['B' + str(per_unit_area_start_row_number)].font = title_font + ws['B' + str(per_unit_area_start_row_number)] = name + ' 单位面积值' + str(report['shopfloor']['area']) + 'M²' category = reporting_period_data['names'] # table_title - ws['B' + str(row_title + 1)].fill = table_fill - ws['B' + str(row_title + 1)].font = title_font - ws['B' + str(row_title + 1)].alignment = c_c_alignment - ws['B' + str(row_title + 1)] = '报告期' - ws['B' + str(row_title + 1)].border = f_border + ws['B' + str(per_unit_area_start_row_number + 1)].fill = table_fill + ws['B' + str(per_unit_area_start_row_number + 1)].font = title_font + ws['B' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment + ws['B' + str(per_unit_area_start_row_number + 1)] = '报告期' + ws['B' + str(per_unit_area_start_row_number + 1)].border = f_border - ws['C' + str(row_title + 1)].font = title_font - ws['C' + str(row_title + 1)].alignment = c_c_alignment - ws['C' + str(row_title + 1)] = '算术平均数' - ws['C' + str(row_title + 1)].border = f_border + ws['C' + str(per_unit_area_start_row_number + 1)].font = title_font + ws['C' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment + ws['C' + str(per_unit_area_start_row_number + 1)] = '算术平均数' + ws['C' + str(per_unit_area_start_row_number + 1)].border = f_border - ws['D' + str(row_title + 1)].font = title_font - ws['D' + str(row_title + 1)].alignment = c_c_alignment - ws['D' + str(row_title + 1)] = '中位数' - ws['D' + str(row_title + 1)].border = f_border + ws['D' + str(per_unit_area_start_row_number + 1)].font = title_font + ws['D' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment + ws['D' + str(per_unit_area_start_row_number + 1)] = '中位数' + ws['D' + str(per_unit_area_start_row_number + 1)].border = f_border - ws['E' + str(row_title + 1)].font = title_font - ws['E' + str(row_title + 1)].alignment = c_c_alignment - ws['E' + str(row_title + 1)] = '最小值' - ws['E' + str(row_title + 1)].border = f_border + ws['E' + str(per_unit_area_start_row_number + 1)].font = title_font + ws['E' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment + ws['E' + str(per_unit_area_start_row_number + 1)] = '最小值' + ws['E' + str(per_unit_area_start_row_number + 1)].border = f_border - ws['F' + str(row_title + 1)].font = title_font - ws['F' + str(row_title + 1)].alignment = c_c_alignment - ws['F' + str(row_title + 1)] = '最大值' - ws['F' + str(row_title + 1)].border = f_border + ws['F' + str(per_unit_area_start_row_number + 1)].font = title_font + ws['F' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment + ws['F' + str(per_unit_area_start_row_number + 1)] = '最大值' + ws['F' + str(per_unit_area_start_row_number + 1)].border = f_border - ws['G' + str(row_title + 1)].font = title_font - ws['G' + str(row_title + 1)].alignment = c_c_alignment - ws['G' + str(row_title + 1)] = '样本标准差' - ws['G' + str(row_title + 1)].border = f_border + ws['G' + str(per_unit_area_start_row_number + 1)].font = title_font + ws['G' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment + ws['G' + str(per_unit_area_start_row_number + 1)] = '样本标准差' + ws['G' + str(per_unit_area_start_row_number + 1)].border = f_border - ws['H' + str(row_title + 1)].font = title_font - ws['H' + str(row_title + 1)].alignment = c_c_alignment - ws['H' + str(row_title + 1)] = '样本方差' - ws['H' + str(row_title + 1)].border = f_border + ws['H' + str(per_unit_area_start_row_number + 1)].font = title_font + ws['H' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment + ws['H' + str(per_unit_area_start_row_number + 1)] = '样本方差' + ws['H' + str(per_unit_area_start_row_number + 1)].border = f_border # table_data for i, value in enumerate(category): - row_data = row_title + 2 + i + row_data = per_unit_area_start_row_number + 2 + i ws['B' + str(row_data)].font = name_font ws['B' + str(row_data)].alignment = c_c_alignment ws['B' + str(row_data)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][ @@ -431,9 +421,9 @@ def generate_excel(report, ######################################################## # Third: 详细数据 - # row_sat+row_title~ row_sat+row_title+time_len: line - # row_sat+1+row_title: table title - # i + row_sat + 2 + 9 * ca_len~: table_data + # detailed_start_row_number~ detailed_start_row_number+time_len: line + # detailed_start_row_number+1: table title + # i + analysis_end_row_number + 2 + 6 * ca_len~: table_data ######################################################## has_timestamps_flag = True if "timestamps" not in reporting_period_data.keys() or \ @@ -448,29 +438,29 @@ def generate_excel(report, ca_len = len(names) time_len = len(timestamps) # title - row_title = 9 * ca_len - # row_st == row_statistical analysis table - row_sat = 12 + 3 * ca_len + line_charts_row_number = 6 * ca_len + analysis_end_row_number = 12 + 3 * ca_len + detailed_start_row_number = analysis_end_row_number + line_charts_row_number + 1 - ws['B' + str(row_sat+row_title)].font = title_font - ws['B' + str(row_sat+row_title)] = name + ' 详细数据' + ws['B' + str(detailed_start_row_number)].font = title_font + ws['B' + str(detailed_start_row_number)] = name + ' 详细数据' # table_title - ws['B' + str(row_sat+1+row_title)].fill = table_fill - ws['B' + str(row_sat+1+row_title)].font = name_font - ws['B' + str(row_sat+1+row_title)].alignment = c_c_alignment - ws['B' + str(row_sat+1+row_title)] = "时间" - ws['B' + str(row_sat+1+row_title)].border = f_border + ws['B' + str(detailed_start_row_number+1)].fill = table_fill + ws['B' + str(detailed_start_row_number+1)].font = name_font + ws['B' + str(detailed_start_row_number+1)].alignment = c_c_alignment + ws['B' + str(detailed_start_row_number+1)] = "时间" + ws['B' + str(detailed_start_row_number+1)].border = f_border for i in range(0, ca_len): col = chr(ord('C') + i) - ws[col + str(row_sat+1+row_title)].font = name_font - ws[col + str(row_sat+1+row_title)].alignment = c_c_alignment - ws[col + str(row_sat+1+row_title)] = names[i] + " - (" + reporting_period_data['units'][i] + ")" - ws[col + str(row_sat+1+row_title)].border = f_border + ws[col + str(detailed_start_row_number+1)].font = name_font + ws[col + str(detailed_start_row_number+1)].alignment = c_c_alignment + ws[col + str(detailed_start_row_number+1)] = names[i] + " - (" + reporting_period_data['units'][i] + ")" + ws[col + str(detailed_start_row_number+1)].border = f_border # table_date for i in range(0, time_len): - rows = i + row_sat + 2 + 9 * ca_len + rows = i + detailed_start_row_number + 2 ws['B' + str(rows)].font = name_font ws['B' + str(rows)].alignment = c_c_alignment @@ -487,7 +477,7 @@ def generate_excel(report, ws[col + str(rows)].border = f_border # 小计 - row_subtotals = row_sat + 2 + time_len + 9 * ca_len + row_subtotals = detailed_start_row_number + 2 + time_len ws['B' + str(row_subtotals)].font = name_font ws['B' + str(row_subtotals)].alignment = c_c_alignment ws['B' + str(row_subtotals)] = "小计" @@ -502,26 +492,36 @@ def generate_excel(report, ws[col + str(row_subtotals)].border = f_border ws[col + str(row_subtotals)].number_format = '0.00' - # LineChart + ######################################################## + # third: LineChart + # LineChart requires data from the detailed data table in the Excel file + # so print the detailed data table first and then print LineChart + ######################################################## for i in range(0, ca_len): - lc = LineChart() - lc.title = "报告期消耗" + " - " + names[i] + "(" + reporting_period_data['units'][i] + ")" - lc.style = 10 - lc.height = 8.40 # cm 1.05*8 1.05cm = 30 pt - lc.width = 31 - lc.x_axis.majorTickMark = 'in' - lc.y_axis.majorTickMark = 'in' - times = Reference(ws, min_col=2, min_row=row_sat + 2 + row_title, - max_row=row_sat + 2 + row_title + time_len) - lc_data = Reference(ws, min_col=3 + i, min_row=row_sat + 1 + row_title, - max_row=row_sat + 1 + row_title + time_len) - lc.add_data(lc_data, titles_from_data=True) - lc.set_categories(times) - ser = lc.series[0] + line = LineChart() + line.title = "报告期消耗" + " - " + names[i] + "(" + reporting_period_data['units'][i] + ")" + line.style = 10 + line.x_axis.majorTickMark = 'in' + line.y_axis.majorTickMark = 'in' + line.smooth = True + line.x_axis.crosses = 'min' + line.height = 8.25 + line.width = 24 + line.dLbls = DataLabelList() + line.dLbls.dLblPos = 't' + line.dLbls.showVal = True + times = Reference(ws, min_col=2, min_row=detailed_start_row_number + 2, + max_row=detailed_start_row_number + 2 + time_len) + line_data = Reference(ws, min_col=3 + i, min_row=detailed_start_row_number + 1, + max_row=detailed_start_row_number + 1 + time_len) + line.add_data(line_data, titles_from_data=True) + line.set_categories(times) + ser = line.series[0] ser.marker.symbol = "diamond" - ser.marker.size = 5 - ws.add_chart(lc, 'B' + str(row_sat + 9 * i)) + chart_col = 'B' + chart_cell = str(analysis_end_row_number + 6 * i) + ws.add_chart(line, chart_col + chart_cell) filename = str(uuid.uuid4()) + '.xlsx' wb.save(filename) diff --git a/myems-api/excelexporters/spacestatistics.py b/myems-api/excelexporters/spacestatistics.py index 7798a3f7..3a47901f 100644 --- a/myems-api/excelexporters/spacestatistics.py +++ b/myems-api/excelexporters/spacestatistics.py @@ -5,6 +5,7 @@ from openpyxl.chart import ( LineChart, Reference, ) +from openpyxl.chart.label import DataLabelList from openpyxl.styles import PatternFill, Border, Side, Alignment, Font from openpyxl.drawing.image import Image from openpyxl import Workbook @@ -68,19 +69,16 @@ def generate_excel(report, ws = wb.active # Row height - ws.row_dimensions[1].height = 121 + ws.row_dimensions[1].height = 102 - for i in range(2, 37 + 1): - ws.row_dimensions[i].height = 30 - - for i in range(38, 90 + 1): - ws.row_dimensions[i].height = 30 + for i in range(2, 2000 + 1): + ws.row_dimensions[i].height = 42 # Col width ws.column_dimensions['A'].width = 1.5 - ws.column_dimensions['B'].width = 20.0 + ws.column_dimensions['B'].width = 25.0 - for i in range(ord('C'), ord('I')): + for i in range(ord('C'), ord('L')): ws.column_dimensions[chr(i)].width = 15.0 # Font @@ -116,12 +114,6 @@ def generate_excel(report, wrap_text=False, shrink_to_fit=False, indent=0) - # c_r_alignment = Alignment(vertical='bottom', - # horizontal='center', - # text_rotation=0, - # wrap_text=False, - # shrink_to_fit=False, - # indent=0) # Img img = Image("excelexporters/myems.png") @@ -320,63 +312,63 @@ def generate_excel(report, # Second: 报告期消耗 # 9 + ca_len * 2: title # 10 + ca_len * 2: table title - # row_title + 2 ~ row_title + 2 + ca_len : table_data + # per_unit_area_start_row_number + 2 ~ per_unit_area_start_row_number + 2 + ca_len : table_data ################################################# if has_energy_data_flag: names = reporting_period_data['names'] ca_len = len(names) - row_title = 9 + ca_len * 2 + per_unit_area_start_row_number = 9 + ca_len * 2 - ws['B' + str(row_title)].font = title_font - ws['B' + str(row_title)] = name + ' 单位面积值' - ws['D' + str(row_title)].font = title_font - ws['D' + str(row_title)] = str(report['space']['area']) + 'M²' + ws['B' + str(per_unit_area_start_row_number)].font = title_font + ws['B' + str(per_unit_area_start_row_number)] = name + ' 单位面积值' + ws['D' + str(per_unit_area_start_row_number)].font = title_font + ws['D' + str(per_unit_area_start_row_number)] = str(report['space']['area']) + 'M²' category = reporting_period_data['names'] # table_title - ws['B' + str(row_title + 1)].fill = table_fill - ws['B' + str(row_title + 1)].font = title_font - ws['B' + str(row_title + 1)].alignment = c_c_alignment - ws['B' + str(row_title + 1)] = '报告期' - ws['B' + str(row_title + 1)].border = f_border + ws['B' + str(per_unit_area_start_row_number + 1)].fill = table_fill + ws['B' + str(per_unit_area_start_row_number + 1)].font = title_font + ws['B' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment + ws['B' + str(per_unit_area_start_row_number + 1)] = '报告期' + ws['B' + str(per_unit_area_start_row_number + 1)].border = f_border - ws['C' + str(row_title + 1)].font = title_font - ws['C' + str(row_title + 1)].alignment = c_c_alignment - ws['C' + str(row_title + 1)] = '算术平均数' - ws['C' + str(row_title + 1)].border = f_border + ws['C' + str(per_unit_area_start_row_number + 1)].font = title_font + ws['C' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment + ws['C' + str(per_unit_area_start_row_number + 1)] = '算术平均数' + ws['C' + str(per_unit_area_start_row_number + 1)].border = f_border - ws['D' + str(row_title + 1)].font = title_font - ws['D' + str(row_title + 1)].alignment = c_c_alignment - ws['D' + str(row_title + 1)] = '中位数' - ws['D' + str(row_title + 1)].border = f_border + ws['D' + str(per_unit_area_start_row_number + 1)].font = title_font + ws['D' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment + ws['D' + str(per_unit_area_start_row_number + 1)] = '中位数' + ws['D' + str(per_unit_area_start_row_number + 1)].border = f_border - ws['E' + str(row_title + 1)].font = title_font - ws['E' + str(row_title + 1)].alignment = c_c_alignment - ws['E' + str(row_title + 1)] = '最小值' - ws['E' + str(row_title + 1)].border = f_border + ws['E' + str(per_unit_area_start_row_number + 1)].font = title_font + ws['E' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment + ws['E' + str(per_unit_area_start_row_number + 1)] = '最小值' + ws['E' + str(per_unit_area_start_row_number + 1)].border = f_border - ws['F' + str(row_title + 1)].font = title_font - ws['F' + str(row_title + 1)].alignment = c_c_alignment - ws['F' + str(row_title + 1)] = '最大值' - ws['F' + str(row_title + 1)].border = f_border + ws['F' + str(per_unit_area_start_row_number + 1)].font = title_font + ws['F' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment + ws['F' + str(per_unit_area_start_row_number + 1)] = '最大值' + ws['F' + str(per_unit_area_start_row_number + 1)].border = f_border - ws['G' + str(row_title + 1)].font = title_font - ws['G' + str(row_title + 1)].alignment = c_c_alignment - ws['G' + str(row_title + 1)] = '样本标准差' - ws['G' + str(row_title + 1)].border = f_border + ws['G' + str(per_unit_area_start_row_number + 1)].font = title_font + ws['G' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment + ws['G' + str(per_unit_area_start_row_number + 1)] = '样本标准差' + ws['G' + str(per_unit_area_start_row_number + 1)].border = f_border - ws['H' + str(row_title + 1)].font = title_font - ws['H' + str(row_title + 1)].alignment = c_c_alignment - ws['H' + str(row_title + 1)] = '样本方差' - ws['H' + str(row_title + 1)].border = f_border + ws['H' + str(per_unit_area_start_row_number + 1)].font = title_font + ws['H' + str(per_unit_area_start_row_number + 1)].alignment = c_c_alignment + ws['H' + str(per_unit_area_start_row_number + 1)] = '样本方差' + ws['H' + str(per_unit_area_start_row_number + 1)].border = f_border # table_data for i, value in enumerate(category): - row_data = row_title + 2 + i + row_data = per_unit_area_start_row_number + 2 + i ws['B' + str(row_data)].font = name_font ws['B' + str(row_data)].alignment = c_c_alignment ws['B' + str(row_data)] = reporting_period_data['names'][i] + " (" + reporting_period_data['units'][ @@ -433,9 +425,9 @@ def generate_excel(report, ######################################################## # Third: 详细数据 - # row_sat+row_title~ row_sat+row_title+time_len: line - # row_sat+1+row_title: table title - # i + row_sat + 2 + 10 * ca_len~: table_data + # analysis_end_row_number~ analysis_end_row_number+time_len: line + # analysis_end_row_number+1+line_charts_row_number: table title + # i + analysis_end_row_number + 2 + 10 * ca_len~: table_data ######################################################## has_timestamps_flag = True if "timestamps" not in reporting_period_data.keys() or \ @@ -450,29 +442,29 @@ def generate_excel(report, ca_len = len(names) time_len = len(timestamps) # title - row_title = 10 * ca_len - # row_st == row_statistical analysis table - row_sat = 12 + 3 * ca_len - - ws['B' + str(row_sat+row_title)].font = title_font - ws['B' + str(row_sat+row_title)] = name + ' 详细数据' + line_charts_row_number = 6 * ca_len + analysis_end_row_number = 12 + 3 * ca_len + detailed_start_row_number = analysis_end_row_number + line_charts_row_number + 1 + + ws['B' + str(detailed_start_row_number)].font = title_font + ws['B' + str(detailed_start_row_number)] = name + ' 详细数据' # table_title - ws['B' + str(row_sat+1+row_title)].fill = table_fill - ws['B' + str(row_sat+1+row_title)].font = name_font - ws['B' + str(row_sat+1+row_title)].alignment = c_c_alignment - ws['B' + str(row_sat+1+row_title)] = "时间" - ws['B' + str(row_sat+1+row_title)].border = f_border + ws['B' + str(detailed_start_row_number + 1)].fill = table_fill + ws['B' + str(detailed_start_row_number + 1)].font = name_font + ws['B' + str(detailed_start_row_number + 1)].alignment = c_c_alignment + ws['B' + str(detailed_start_row_number + 1)] = "时间" + ws['B' + str(detailed_start_row_number + 1)].border = f_border for i in range(0, ca_len): col = chr(ord('C') + i) - ws[col + str(row_sat+1+row_title)].font = name_font - ws[col + str(row_sat+1+row_title)].alignment = c_c_alignment - ws[col + str(row_sat+1+row_title)] = names[i] + " - (" + reporting_period_data['units'][i] + ")" - ws[col + str(row_sat+1+row_title)].border = f_border + ws[col + str(detailed_start_row_number + 1)].font = name_font + ws[col + str(detailed_start_row_number + 1)].alignment = c_c_alignment + ws[col + str(detailed_start_row_number + 1)] = names[i] + " - (" + reporting_period_data['units'][i] + ")" + ws[col + str(detailed_start_row_number + 1)].border = f_border # table_date for i in range(0, time_len): - rows = i + row_sat + 2 + 10 * ca_len + rows = i + detailed_start_row_number + 2 ws['B' + str(rows)].font = name_font ws['B' + str(rows)].alignment = c_c_alignment @@ -489,7 +481,7 @@ def generate_excel(report, ws[col + str(rows)].border = f_border # 小计 - row_subtotals = row_sat + 2 + time_len + 10 * ca_len + row_subtotals = detailed_start_row_number + 2 + time_len ws['B' + str(row_subtotals)].font = name_font ws['B' + str(row_subtotals)].alignment = c_c_alignment ws['B' + str(row_subtotals)] = "小计" @@ -504,26 +496,35 @@ def generate_excel(report, ws[col + str(row_subtotals)].border = f_border ws[col + str(row_subtotals)].number_format = '0.00' - # LineChart + ######################################################## + # third: LineChart + # LineChart requires data from the detailed data table in the Excel file + # so print the detailed data table first and then print LineChart + ######################################################## for i in range(0, ca_len): - lc = LineChart() - lc.title = "报告期消耗" + " - " + names[i] + "(" + reporting_period_data['units'][i] + ")" - lc.style = 10 - lc.height = 8.40 # cm 1.05*8 1.05cm = 30 pt - lc.width = 31 - lc.x_axis.majorTickMark = 'in' - lc.y_axis.majorTickMark = 'in' - times = Reference(ws, min_col=2, min_row=row_sat + 2 + row_title, - max_row=row_sat + 2 + row_title + time_len) - lc_data = Reference(ws, min_col=3 + i, min_row=row_sat + 1 + row_title, - max_row=row_sat + 1 + row_title + time_len) - lc.add_data(lc_data, titles_from_data=True) - lc.set_categories(times) - ser = lc.series[0] + line = LineChart() + line.title = "报告期消耗" + " - " + names[i] + "(" + reporting_period_data['units'][i] + ")" + line.style = 10 + line.x_axis.majorTickMark = 'in' + line.y_axis.majorTickMark = 'in' + line.smooth = True + line.x_axis.crosses = 'min' + line.height = 8.25 + line.width = 24 + line.dLbls = DataLabelList() + line.dLbls.dLblPos = 't' + line.dLbls.showVal = True + times = Reference(ws, min_col=2, min_row=detailed_start_row_number + 2, + max_row=detailed_start_row_number + 2 + time_len) + line_data = Reference(ws, min_col=3 + i, min_row=detailed_start_row_number + 1, + max_row=detailed_start_row_number + 1 + time_len) + line.add_data(line_data, titles_from_data=True) + line.set_categories(times) + ser = line.series[0] ser.marker.symbol = "diamond" ser.marker.size = 5 - ws.add_chart(lc, 'B' + str(row_sat + 10 * i)) + ws.add_chart(line, 'B' + str(analysis_end_row_number + 6 * i)) filename = str(uuid.uuid4()) + '.xlsx' wb.save(filename) diff --git a/myems-api/reports/combinedequipmentstatistics.py b/myems-api/reports/combinedequipmentstatistics.py index bc501981..c24ec5b1 100644 --- a/myems-api/reports/combinedequipmentstatistics.py +++ b/myems-api/reports/combinedequipmentstatistics.py @@ -5,6 +5,7 @@ import config from datetime import datetime, timedelta, timezone from core import utilities from decimal import Decimal +import excelexporters.combinedequipmentstatistics class Reporting: @@ -560,4 +561,11 @@ class Reporting: "values": parameters_data['values'] } + # export result to Excel file and then encode the file to base64 string + result['excel_bytes_base64'] = excelexporters.combinedequipmentstatistics.export(result, + combined_equipment['name'], + reporting_start_datetime_local, + reporting_end_datetime_local, + period_type) + resp.body = json.dumps(result)