To do this, is bit tricky as only fetch doc.owner is standard.  Below i will share a sample code and how the approver level along with comments in chat with developer using client ref: CTPC 


Here is a sample code 


<p><strong>Doc. Prepared By : {{frappe.get_fullname(doc.owner) }}</strong></p>
{% set check_user= frappe.db.get_value("Comment", {"reference_doctype": "Material Request", "reference_name": doc.name, "content": "Pending - Final Approver"},["comment_email"]) %}


<p><strong>Doc. 1st level Approved By : {{frappe.get_fullname(check_user) }}</strong></p>
{% set approver_user= frappe.db.get_value("Comment", {"reference_doctype": "Material Request", "reference_name": doc.name, "content": "Final Approved"},["comment_email"]) %}
<p><strong>Doc. Final Approved By : {{frappe.get_fullname(approver_user) }}</strong></p>




In ERPNEXT,

We modify the code and relate also to the approver flow in terms of the approver roles and the doc type 






Try also to test below info obtained from this link 


https://discuss.erpnext.com/t/fetching-name-of-creator-submittor-approvar-of-doc-in-print/8229/3



if you apply workflow on any document. the related information is going into Communication table.

you have to fetch info from there and have to handle it in Print Format.

{% set test = frappe.get_list(“Communication”, filters={“reference_name”: doc.name}, fields = [“user”,“subject”]) %}

and then iterate through test and print according to user. subject contains the workflow state info


{% set test = frappe.get_list(“Communication”, filters={“reference_name”: doc.name}, fields = [“user”,“subject”]) %}
{%- for row in test -%}
{% if row.subject == “SM Approved” %}
{{ row.user}}
{% endif %}
{% endfor %}

use the above code.
and in if conditions, you can apply all workflow states to print it’s approved user