Creating a table in python docx and use small_caps (python-docx) - python

This is what I have tried:
from docx import Document
from docx.shared import Inches
from docx.shared import Pt
table = document.add_table(rows= 3, cols = 1)
row = table.rows[0]
runner = row.cells[0].paragraphs[0].add_run('Summary')
runner.bold = True
runner.small_caps = True
document.save('demo.docx')
I am trying to create a table and small caps the text but cannot get the syntax right

I have figured how to use small caps for text.
runner_font = runner.font
runner_font.size = Pt(14)
runner_font.small_caps = True
runner_font.bold = True
I believe bold and italic are properties that built in under both add_run and font. But for small_caps, all_caps, color can be called under font only.

Related

TableStyle is overwritten by document style

Because the original project seems inactive I have to replicate my Issue here at StackOverflow.
It seems to me that the global document style does overwrite lower styles e.g. TableStyle. I assume I misunderstand the concept here.
See this code as an example
#!/usr/bin/env python3
import os
import docx
document = docx.Document()
document.styles['Normal'].font.name = 'Fira Mono'
document.styles['Normal'].font.size = docx.shared.Pt(8)
my_tab_style = document.styles.add_style('MyTab', docx.enum.style.WD_STYLE_TYPE.TABLE)
my_tab_style.font.name = 'Fira Sans'
my_tab_style.font.size = docx.shared.Pt(20)
p = document.add_paragraph('Should be Fira Mono 8pt')
tab = document.add_table(rows=1, cols=1, style='MyTab')
tab.rows[0].cells[0].text = 'Should be Fira Sans 20pt'
document.save('test.docx')
os.system('start test.docx')
I would expect the document text in "Fira Mono 8pt" and the table content in "Fira Sans 20pt". But it isn't.
When you outcomment the document style lines
# document.styles['Normal'].font.name = 'Fira Mono'
# document.styles['Normal'].font.size = docx.shared.Pt(8)
the table style is taken into account.

How to define a function to add cell colour for a table that created by python-docx?

I want to define a function to filling header colour,
for now, I am just hard code every object.
Here is the code I used, I tried to define a function to add cell colour.
The error msg shown below:
from docx import Document
from openpyxl import load_workbook
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from zmq import NULL
document = Document()
k=1
for k in range (1,5):
table = document.add_table(rows=2, cols=3)
table.cell(0,0).text = ('Type')
table.cell(0,1).text = ('Value')
table.cell(0,2).text = ('Connections')
def set_table_header_bg_color(table.rows[row_ix].cell):
"""
set background shading for Header Rows
"""
tblCell = cell._tc
tblCellProperties = tc.get_or_add_tcPr()
clShading = OxmlElement('w:shd')
clShading.set(qn('w:fill'), "00519E") #Hex of Dark Blue Shade {R:0x00, G:0x51, B:0x9E}
tblCellProperties.append(clShading)
return cell
for each_row in table.rows :
for each_cell in each_row.cells:
set_table_header_bg_color(each_cell)
Could you guys help me to solve this error?
I copy this function from https://stackoverflow.com/a/62079054/18540814
but the function seems cannot use in my case......
Some things to note
You need to be careful of indentation; 'def' should not be indented and don't place it in the middle of a section of code.
There is no need to initialise a variable when assigning to a range; k=1 isn't needed the range is assigned on the next line.
No need to return the 'cell' the def is a function to change the shading on a cell, there is nothing to return.
As you have written it you are creating 3 tables with the 'k' range not sure if that is your intent.
from docx import Document
from docx.oxml.shared import qn
from docx.oxml.xmlchemy import OxmlElement
doc_name = 'doc_w_tables.docx'
document = Document()
tables = document.tables
def set_table_header_bg_color(tc):
"""
set background shading for Header Rows
"""
tblCellProperties = tc._element.tcPr
clShading = OxmlElement('w:shd')
clShading.set(qn('w:fill'), "00519E") # Hex of Dark Blue Shade {R:0x00, G:0x51, B:0x9E}
tblCellProperties.append(clShading)
for k in range(0, 3):
table = document.add_table(rows=2, cols=3)
table.cell(0, 0).text = 'Type'
table.cell(0, 1).text = 'Value'
table.cell(0, 2).text = 'Connections'
for j in range(0,3):
set_table_header_bg_color(table.rows[0].cells[j])
document.save(doc_name)
docx python-docx

cannot make text rtl with python-docx

yes i know many questions about this issue exists but i couldn't make any of them work.
i have python 3.7 and python-docx 0.8.11.
i have tried many solutions including this one
from docx import Document, enum
document = Document()
mystyle = document.styles.add_style('mystyle', enum.style.WD_STYLE_TYPE.CHARACTER)
run = document.add_paragraph().add_run(text)
run.style = mystyle
font = run.font
font.rtl = True
document.save('test.docx')
also
from docx import Document, enum
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
doc = Document()
rtlstyle = doc.styles.add_style('rtl', enum.style.WD_STYLE_TYPE.PARAGRAPH)
rtlstyle.font.rtl = True
p = doc.add_paragraph(text)
p.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT
p.style = rtlstyle
doc.save('test.docx')
nothing worked so far
see this : https://stackoverflow.com/posts/73133074/revisions
also as mensiond here put this before your text: u'\u202B' + "your text"
or u'\u202E' if didn't work

How to apply strike-through using python-docx

My problem is that when I apply the strike-through or double strike-through formatting and save the file it is not reflected in output file.
Following code does not do the trick:
from docx import Document
document = Document()
p = document.add_paragraph()
p.add_run('Strike through the following text').strike = True
document.save('demo.docx')
This should do the job:
p.add_run('Strike through the following text').font.strike = True
strike is a property of the font object : docs
EDIT
If multiple font properties were to be changed the code should be :
sentence = p.add_run('Strike through the following text')
sentence.font.strike = True
sentence.font.name = 'Comic Sans MS'

Python Reportlab PDF - Centering Text on page

I am using ReportLab to generate a pdf dynamically with python.
I would like a line of text to be centered on a page. Here is the specific code I currently have, but do not know how to center the text horizontally.
header = p.beginText(190, 740)
header.textOut("Title of Page Here")
# I know i can use TextLine etc in place of textOut
p.drawText(header)
The text displays and I can manually move the left position so the text looks centered, but I need this to be centered programmatically since the text will be dynamic and I don't know how much text there will be.
The reportlab canvas has a drawCentredString method. And yes, they spell it like that.
We’re British, dammit, and proud of
our spelling!
Edit:
As for text objects, I'm afraid you don't. You can do something along those lines, though:
from reportlab.pdfbase.pdfmetrics import stringWidth
from reportlab.rl_config import defaultPageSize
PAGE_WIDTH = defaultPageSize[0]
PAGE_HEIGHT = defaultPageSize[1]
text = "foobar foobar foobar"
text_width = stringWidth(text)
y = 1050 # wherever you want your text to appear
pdf_text_object = canvas.beginText((PAGE_WIDTH - text_width) / 2.0, y)
pdf_text_object.textOut(text) # or: pdf_text_object.textLine(text) etc.
You can use other page sizes, obviously.
I just needed this too, and wrote this:
def createTextObject(canv, x, y, text, style, centered=False):
font = (style.fontName, style.fontSize, style.leading)
lines = text.split("\n")
offsets = []
if centered:
maxwidth = 0
for line in lines:
offsets.append(canv.stringWidth(line, *font[:2]))
maxwidth = max(*offsets)
offsets = [(maxwidth - i)/2 for i in offsets]
else:
offsets = [0] * len(lines)
tx = canv.beginText(x, y)
tx.setFont(*font)
for offset, line in zip(offsets, lines):
tx.setXPos(offset)
tx.textLine(line)
tx.setXPos(-offset)
return tx
You can use Flowable object like Paragraph and assign alignment value to 1:
styles = getSampleStyleSheet()
title_style = styles['Heading1']
title_style.alignment = 1
title = Paragraph("Hello Reportlab", title_style)
story.append(title)
This example will create a pdf document with centered text:
from flask import make_response
import io
from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.lib.styles import getSampleStyleSheet
story=[]
pdf_doc = io.BytesIO()
doc = SimpleDocTemplate(pdf_doc)
styles = getSampleStyleSheet()
title_style = styles['Heading1']
title_style.alignment = 1
title = Paragraph("Hello Reportlab", title_style)
story.append(title)
doc.build(story)
content = pdf_doc.getvalue()
#output to browser
response = make_response(content)
response.mimetype = 'application/pdf'
return response
If you want the text to be floaten to the left, you need to change alignment to 0:
title_style.alignment = 0
If you want the text to be floaten to the right, you need to change alignment to 2:
title_style.alignment = 2
Try:
<para alignment="center">
As Per Reference : http://two.pairlist.net/pipermail/reportlab-users/2006-June/005092.html
In your case:
header.textOut("<"para alignment='center'>"Title of Page Here")
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
doc = SimpleDocTemplate("form_letter.pdf",pagesize=letter,
rightMargin=72,leftMargin=72,
topMargin=72,bottomMargin=18)
Story = []
styles = getSampleStyleSheet()
title_style = styles['Heading1']
title_style.alignment = 1
title = Paragraph("Welcome to india", title_style)
Story.append(title)
doc.build(Story)

Categories

Resources