Файл docx на основе шаблона при помощи PHP

Довольно часто встречается задача автоматизировать заполнение всяческих заявлений..ну например в бухгалтерию. Это вполне можно сделать и на PHP, позволив пользователю на форме веб страницы заполнить основные данные, а затем отдав ему уже сформированный на основе шаблона файл формата docx (файл docx на основе шаблона).

HTML часть может выглядеть примерно так:

<div class="rendered-form">
    <div class="formbuilder-text form-group field-position_at_work">
        <label for="position_at_work" class="formbuilder-text-label">Ваша должность
            <br>
        </label>
        <input type="text" placeholder="Наиглавнейший церемонимейстер" class="form-control" name="position_at_work" access="false" id="position_at_work">
    </div>
    <div class="formbuilder-text form-group field-me_unit">
        <label for="me_unit" class="formbuilder-text-label">Подразделение</label>
        <input type="text" placeholder="Отдел развития и автоматизации" class="form-control" name="me_unit" access="false" id="me_unit">
    </div>
    <div class="formbuilder-text form-group field-me_name">
        <label for="me_name" class="formbuilder-text-label">Ваше ФИО
            <br>
        </label>
        <input type="text" placeholder="Иванов Иван Иванович" class="form-control" name="me_name" access="false" id="me_name">
    </div>
    <div class="formbuilder-date form-group field-date_start">
        <label for="date_start" class="formbuilder-date-label">Дата начала отпуска
            <br>
        </label>
        <input type="date" class="form-control" name="date_start" access="false" id="date_start">
    </div>
    <div class="formbuilder-number form-group field-long_vacation">
        <label for="long_vacation" class="formbuilder-number-label">Продолжительность отпуска
            <br>
        </label>
        <input type="number" class="form-control" name="long_vacation" access="false" value="14" min="1" max="31" id="long_vacation">
    </div>
    <div class="formbuilder-button form-group field-button-1714717346219">
        <button onclick="CreateZay()" type="button" class="btn-success btn" name="button-1714717346219" access="false" style="success" id="button-1714717346219">Сформировать заявление
            <br>
        </button>
    </div>
</div>

На странице увидим что-то вроде:

файл docx на основе шаблона

На JavaScript создам функцию — обработчик нажатия на кнопку «Сформировать заявление». Функция делает запрос на сервер, а в ответ получает сформированный файл. Браузер автоматически предложит его сохранить.

function CreateZay(){
  console.log("--создаётся заявление..");  
  
        var xhr = new XMLHttpRequest();
        xhr.open('POST', '/sever/zayav.php', true);
        
        xhr.responseType = 'blob';     
        xhr.onload = function(e) {
            if (this.status == 200) {
                var link=document.createElement('a');
                link.href=window.URL.createObjectURL(this.response);                
                link.download="result.docx";
                link.click();
            }
            else {
                console.log(e);
            }
        };     
        var form_data = new FormData();        
        form_data.append("position_at_work", position_at_work.value);
        form_data.append("me_unit", me_unit.value);
        form_data.append("me_name", me_name.value);
        form_data.append("date_start", date_start.value);
        form_data.append("long_vacation", long_vacation.value);
        xhr.send(form_data);                 
};  

С клиентской частью (ну которая в браузере) разобрались. Теперь займемся сервером. Чтобы ничего не изобретать, воспользуемся пакетом phpoffice/phpword:

composer require phpoffice/phpword

Далее подготовим файл-шаблон. Можно в любом редакторе, который поддерживает расширение docx. В файле , те части которые мы хотим заменить, обрамляем ${имя_переменноя}, чтобы получилось например что-то вроде:

Далее, серверная часть, которая заполняет непосредственно сам шаблон:

<?php
$dt_start=strtotime($_POST["date_start"]);
$dt_end=strtotime($_POST["date_start"]." ".$_POST["long_vacation"]." day");

$newformat_start = date('d.m.Y',$dt_start);
$newformat_end = date('d.m.Y',$dt_end);

//var_dump($_POST);
//die();

require $_SERVER["DOCUMENT_ROOT"].'/sever/phpword/autoload.php';
//создаем класс
$phpWord = new  \PhpOffice\PhpWord\PhpWord(); 
$_doc = new \PhpOffice\PhpWord\TemplateProcessor('templates/template_1.docx');


$_doc->setValue('position_at_work', $_POST["position_at_work"]); 
$_doc->setValue('me_unit', $_POST["me_unit"]); 
$_doc->setValue('me_name', $_POST["me_name"]); 
$_doc->setValue('long_vacation', $_POST["long_vacation"]); 
$_doc->setValue('date_start', $newformat_start); 
$_doc->setValue('date_end', $newformat_end); 

$res=$_doc->saveAs($_SERVER["DOCUMENT_ROOT"]."/sever/tmp.docx");

$fil=file_get_contents($_SERVER["DOCUMENT_ROOT"]."/sever/tmp.docx");
echo $fil;

В результате мы получили файл docx. Другие статьи по PHP можете почитать здесь