File size: 3,050 Bytes
e0bab69 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
"""Generate the downloadable Word report."""
import io, tempfile
from docx import Document
from docx.shared import Inches
import streamlit as st
from config import FREQUENCIES
from helpers import calc_abs_area
def generate_docx() -> bytes:
doc = Document()
doc.add_heading("Room Acoustics Analysis Report", 0)
# 1 ─ Input data
doc.add_heading("1 Input Data", 1)
doc.add_paragraph(f"Room volume: {st.session_state.room_volume:.2f} m³")
if st.session_state.df_current_rt is not None:
doc.add_heading("Current Reverberation Time", 2)
doc.add_paragraph(st.session_state.df_current_rt.to_string(index=False))
if st.session_state.df_existing_mat is not None:
doc.add_heading("Existing Materials – Coefficients & Areas", 2)
doc.add_paragraph(st.session_state.df_existing_mat.to_string(index=False))
if not st.session_state.df_background_noise.empty:
doc.add_heading("Background-Noise Measurements", 2)
doc.add_paragraph(st.session_state.df_background_noise.to_string(index=False))
if st.session_state.df_spl is not None:
doc.add_heading("Sound-Pressure Levels (SPL)", 2)
doc.add_paragraph(st.session_state.df_spl.to_string())
# 2 ─ Speech-intelligibility (Dots & AI)
doc.add_heading("2 Speech-Intelligibility (Dots & AI)", 1)
if st.session_state.dots_init_dict:
doc.add_heading("Initial Compliance Check", 2)
for loc, dots in st.session_state.dots_init_dict.items():
ai, interp = st.session_state.ai_init_dict.get(loc, (None, ""))
line = f"{loc}: Dots = {dots}"
if ai is not None:
line += f" → AI = {ai:.2f} ({interp})"
doc.add_paragraph(line)
if st.session_state.dots_final_dict:
doc.add_heading("Final Compliance Check", 2)
for loc, dots in st.session_state.dots_final_dict.items():
ai, interp = st.session_state.ai_final_dict.get(loc, (None, ""))
line = f"{loc}: Dots = {dots}"
if ai is not None:
line += f" → AI = {ai:.2f} ({interp})"
doc.add_paragraph(line)
# 3 ─ Figures
doc.add_heading("3 Figures", 1)
def _add(fig, caption):
if fig is None: return
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp:
fig.write_image(tmp.name, scale=4)
doc.add_picture(tmp.name, width=Inches(6))
doc.paragraphs[-1].alignment = 1
doc.add_paragraph(caption, style="Caption")
_add(st.session_state.fig_rt_initial, "Fig 1 Initial RT60 vs Standard Range")
_add(st.session_state.fig_bn_initial, "Fig 2 Initial Background-Noise vs Standard Range")
_add(st.session_state.fig_rt_final, "Fig 3 Final RT60 vs Standard Range")
_add(st.session_state.fig_bn_final, "Fig 4 Final Background-Noise vs Standard Range")
buf = io.BytesIO()
doc.save(buf)
return buf.getvalue()
|