I am generating pdf for my client application using TCPDF by customising footer. My Client wants to show data in footer which are dynamic along with the page number. The problem I am facing is when the data becomes longer than the pdf width the data doesnt move to the next line and some texts are getting cropped.
Can somebody suggest me solution by which I can shift some text to new line? similar to the one be do in HTML by adding <br>.
Or
Is there a way by which the text moves to next line automatically when the length of the text in footer exceeds the pdf width?
Extend the class as per example 3 or use the following code
class MYPDF extends TCPDF {
// Page footer
public function Footer() {
// Position at 15 mm from bottom
$this->SetY(-15);
// Set font
$this->SetFont('helvetica', 'I', 8);
$foot = 'Line 1 \n Line 2 \n 'Page '.$this->getAliasNumPage().'/'.$this->getAliasNbPages()';
$this->MultiCell(0, 10, $foot, 0, 'C');
}
}
// create new PDF document
$pdf = new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
Related
I have created a VirtualList to display books information. My renderer presents each book information as an accordion, where first panel is generic book information (author, title, etc.) and it might have three more panels: annotation, commentary, reviews.
It is working as expected, but I do have formatting problems.
Here is my book renderer:
private final ComponentRenderer<Component, Book> bookRenderer = new ComponentRenderer<>(
book -> {
//info panel
Accordion bookPresentation = new Accordion();
HorizontalLayout bookInfo = new HorizontalLayout();
bookInfo.getStyle().set("background-color", book.getHighlight());
bookInfo.setWidth("100%");
UnorderedList authorsList = createAuthorsList(book.getAuthors());
authorsList.setMinWidth("24%");
VerticalLayout taggedTitle = createTaggedTitle(book);
VerticalLayout stars = createStarRating(book);
VerticalLayout readerRating = createReaderRating(book);
VerticalLayout bookStatus = createStatusField(book);
bookInfo.add(authorsList, taggedTitle, stars, readerRating, bookStatus);
AccordionPanel summary = new AccordionPanel(bookInfo);
summary.addThemeVariants(DetailsVariant.SMALL);
summary.addClassName("book-item");
bookPresentation.add(summary);
//annotation panel
if (book.getAnnotation() != null && !book.getAnnotation().isBlank()) {
TextArea annotation = new TextArea();
annotation.setWidth("75%");
annotation.setValue(book.getAnnotation());
annotation.setReadOnly(true);
annotation.setMaxHeight(MAX_HIGHT);
bookPresentation.add("Аннотация", annotation);
}
if (book.getCommentary() != null && !book.getCommentary().isBlank()) {
TextArea comment = new TextArea();
comment.setValue(book.getCommentary());
comment.setReadOnly(true);
comment.setMaxHeight(MAX_HIGHT);
bookPresentation.add("Комментарий", comment);
}
if (book.getReadersReviews() != null && !book.getReadersReviews().isEmpty()) {
Accordion reviews = new Accordion();
for (ReadersReview review : book.getReadersReviews()) {
TextArea reviewText = new TextArea();
reviewText.setMaxHeight(MAX_HIGHT);
reviewText.setValue(review.getReaderComment());
if(user == null || !user.getReaderName().equalsIgnoreCase(review.getReviewerName())) {
reviewText.setReadOnly(true);
}
reviews.add(review.getReviewerName(), reviewText);
}
bookPresentation.add("Мнение читателей", reviews);
}
return bookPresentation;
});
And here is what I am getting on the screen:
I have separation line between accordion panels, but no separation between two items (books) in the list. I'd prefer to have it otherwise. At least I do need to separate one book from another. I did search Vaadin documentation but didn't find any settings that can display such separator between VirtualList items. I'd like to have this separator to be of a different color and line width than accordion panel separator. I followed Joel advise and added border to the styles.css file and added CSS class to the accordion or to its first panel, but it didn't have any effect.
The gap between items in the displayed VirtualList varies significantly as it can be seen on the screenshot. Sometimes items go one after another, and sometimes distance between them can reach 2+ inches. How can I set a fixed distance between these items?
I have set the width of bookInfo panel to 100% but as you can see, it occupies significantly less. I also specify the width of every component and sum of them should be equal to 100%, but as you can see they aren't aligned. What I am missing there?
To put a separator line between items, you'll want to use CSS. One way to do it is to set a CSS class name on your VirtualList items (via your renderer), say "book-item", and then use some CSS like the following:
.book-item {
border-top: 3px solid darkgray;
}
.book-item:first-of-type {
border-top: none;
}
I'm very new to Oracle Apex and currently I want to use and customize Gantt charts. What I want to achieve it to show line breaks in the row-labels. Currently every newline character gets cut out and I am not sure where this happens and how I can prevent this.
The marked text contains newline characters. Don't be confused by the <br>, I just tests if this does the trick.
I just want to show more some information in the for each row. If there is another more elegant way, it would be very nice to give a tip.
Update:
I did some research and found a very nice example on a similar topic, in this case to create a custom tooltip https://youtu.be/2rZAIR_0tNg?t=2532.
I wanted to do the same thing for the row_axis label renderer, but nothing gets visualized.
The render function I use:
function custom_row_axis_label_renderer(data_context){
var row_axis_label_elem = document.createElement("g");
$("row_axis_label_elem").addClass("custom_row_axis_label");
row_axis_label_elem.innerHTML = '<text font-size="14px">Hello World</text>';
console.log(row_axis_label_elem);
return row_axis_label_elem;
}
The rendered element kind of exists, but it's get the size 0x0 from somewhere.
Am I missing something here?
Regards,
Nik
Meanwhile I found the solution on how to build a custom renderer. The main part I didn't new is that you NEED to pass x and y coordinates to have the new label to be rendered correctly. I found a proper example the the oracle forum, but unfortunately I can't find the link anymore to give credit to the original example.
Here is my code. It creates two text elements below each other to achieve a mocked line break and it adds a yellow icon. Of course you can use the data_context object to access the actual label. Add this part in the "Function and Global Variable Declaration
" part of your page:
custom_row_axis_label_renderer = function (data_context){
var row_axis_label_elem = document.createElementNS("http://www.w3.org/2000/svg", "g");
var upper_text = document.createElementNS("http://www.w3.org/2000/svg", "text");
var lower_text = document.createElementNS("http://www.w3.org/2000/svg", "text");
var icon_node = document.createElementNS("http://www.w3.org/2000/svg", "circle");
upper_text.textContent = "Hello";
upper_text.setAttribute("dominant-baseline","text-before-edge");
upper_text.setAttribute("class","oj-gantt-row-label");
upper_text.setAttribute("font-size","14px");
upper_text.setAttribute("text-anchor","end");
upper_text.setAttribute("x","220");
upper_text.setAttribute("y","5");
lower_text.textContent = "World";
lower_text.setAttribute("dominant-baseline","text-before-edge");
lower_text.setAttribute("class","oj-gantt-row-label");
lower_text.setAttribute("font-size","14px");
lower_text.setAttribute("text-anchor","end");
lower_text.setAttribute("x","220");
lower_text.setAttribute("y","25");
icon_node.setAttribute("cx","240");
icon_node.setAttribute("cy","25");
icon_node.setAttribute("r","8");
icon_node.setAttribute("class","u-color-7");
row_axis_label_elem.appendChild(upper_text);
row_axis_label_elem.appendChild(lower_text);
row_axis_label_elem.appendChild(icon_node);
return row_axis_label_elem;
}
Also you need to set the renderer of the row-axis-label. I also made the rows and task a little bit bigger to have enough space for two lines of text in the label. Add this in the "JavaScript Initialization Code" in the attriutes of you chart:
function( options ){
options.rowAxis.label = {renderer : custom_row_axis_label_renderer};
options.rowDefaults = {height : 60};
options.taskDefaults = {height: 40};
return options;
}
We are building a graphical user interface with QtQuick/QML. We have some dynamic, multi-line text coming from a database, which should be displayed in the application. Currently, we are using the Text element to display the text. However, we need some QML components inline embedded into the text. For this, the text coming from the database contains placeholders such as ::checkbox|1:: which should then be replaced and displayed by the program.
In HTML, this is easy, you can simply mix inline elements with text to produce a result like this:
but in QML, this seems to be more difficult, as Text elements cannot be word-wrapped into two halves if there is not enough space (both the text and the container size should be dynamic).
The best solution we could come up with, is creating a Flow layout with one Text element for each word, but this seems too hacky.
Using RichText with HTML is not enogh, since we really need our custom QML elements in the text.
Also, we want to avoid using a WebView due to performance reasons.
Is there a sophisticated way to implement this with QML/C++ only?
You can create custom widgets and embed them into QML:
Writing QML Extensions with C++
I haven't tried placing something in the middle, but I did try adding a tag to the beginning (and I might try adding a tag at the end).
QML's Text has a lineLaidOut signal that let's you indent the first line of text.
http://doc.qt.io/qt-5/qml-qtquick-text.html#lineLaidOut-signal
Here's what I did:
Text {
text: issue.summary
onLineLaidOut: {
if (line.number == 0) {
var indent = tagRect.width + tagRect.rightMargin
line.x += indent
line.width -= indent
}
}
Rectangle {
id: tagRect
implicitWidth: padding + tagText.implicitWidth + padding
implicitHeight: padding + tagText.implicitHeight + padding
color: "#400"
property int padding: 2
property int rightMargin: 8
radius: 3
Text {
id: tagText
anchors.centerIn: parent
text: issue.product
color: "#fff"
}
}
}
Currently, I am working on a GUI text editor with python and tkinter. Thanks to the great people at SO (thank you Rinzler), I have managed to modify the font of the text. However, I am unable to save the font and font size to the txt file.
I know that this should be possible as Notepad can modify and save a txt file with a specified font.
This is the code to save to a file:
def file_saveas():
filename = tkFileDialog.asksaveasfile(mode='w', defaultextension=".txt")
if filename is None: # asksaveasfile return `None` if dialog closed with "cancel".
return
text2save = str(textPad.get(1.0, END)) # starts from `1.0`, not `0.0`
filename.write(text2save)
filename.close()
print filename
This is the code (courtesy of Rinzler) to change the font:
def choose_font():
global root, textPad # I hate to use global, but for simplicity
t = Tkinter.Toplevel()
font_name = Tkinter.Label(t, text='Font Name: ')
font_name.grid(row=0, column=0, sticky='nsew')
enter_font = Tkinter.Entry(t)
enter_font.grid(row=0, column=1, sticky='nsew')
font_size = Tkinter.Label(t, text='Font Size: ')
font_size.grid(row=1, column=0, sticky='nsew')
enter_size = Tkinter.Entry(t)
enter_size.grid(row=1, column=1, sticky='nsew')
# associating a lambda with the call to text.config()
# to change the font of text (a Text widget reference)
ok_btn = Tkinter.Button(t, text='Apply Changes',
command=lambda: textPad.config(font=(enter_font.get(),
enter_size.get())))
print font
ok_btn.grid(row=2, column=1, sticky='nsew')
done = Tkinter.Button(t, text='Get rid of Pushy!', command=t.destroy)
done.grid(row=4, column=1, sticky='nsew')
# just to make strechable widgets
# you don't strictly need this
for i in range(2):
t.grid_rowconfigure(i, weight=1)
t.grid_columnconfigure(i, weight=1)
t.grid_rowconfigure(2, weight=1)
Finally, this is the code that reads the font and other configuration information:
font = (fontname, size)
textPad.config(
borderwidth=0,
font=font ,
foreground="green",
background="black",
insertbackground="white", # cursor
selectforeground="blue", # selection
selectbackground="#008000",
wrap="word",
width=64,
undo=True, # Tk 8.4
)
I have searched the internet without coming up with any answers as to why the font and text size are not saved. Any help would be greatly appreciated.
I am using python 2.7.7 , Tkinter, and this is being run on Windows 7.
Any help manipulation an rtf file would also be helpful (currently, I see the tags and not the end format).
There is no support for this in tkinter. You will have to pick a file fomat that supports fonts (rtf, .docx, .html, etc), convert the data in the widget to this format, and then write it to a file.
Notepad can only have a custom font and size for its editor window, it doesn't save it to the file, it just remembers the user's custom settings, and applies them to its window when you use it.
The tkinter text widget can be horrible to save formatting to another format, I've tried converting it to XML to save to a .docx but I haven't been successful. I have used my own format which is a plain text file with an 'index' of the tkinter Text widget tags at the start and their line&column indexes, then a marker for where the document begins, then the document. This cannot hold images though, and it opens with all the formatting index when you open it in another word processor.
XML is ideal for opening and saving the tkinter text contents - use an xml parser to open, then wite a recursive function to add text with tags as you go. (If you want rich text, this, like xml, is an iterative format - elements inside elements, so could be done like i'm describing below for xml, but you need to write your own rich text parser)
import xml.etree.ElementTree as etree
e = etree.fromstring(string)
#create an element tree of the xml file
insert_iter(e)
#call the recursive insert function
def insert_iter(element):
#recursive insert function
text.insert("end", element.text, tagname)
#insert the elements text
for child in element:
insert_iter(child)
#iterate through the element's child elements, calling the recursive function for each
text.insert("end", child.tail, tagname)
#insert the text after the child element
text.tag_config(tagname, **attrib)
#configure the text
'attrib' is a dictionary eg. {"foreground":"red", "underline":True} would make the text you insert have red font and black underline,
'tagname' is a random string, and needs to be automatically created by your program
To save the file, make a function to do the reverse. I wouldn't bother with using the xml library for this - as tkinter outputs the correct format, just write it manually, but make sure to escape it
from xml.sax.saxutils import escape
data = text.dump("1.0", "end")
print(data[0:500]) # print some of the output just to show how the dump method works
output = ''
#get contents of text widget (including all formatting, in order) and create a string to add the output file to
for line in data:
if line[0] == "text":
#add the plain text to the output
output += escape(line[1])
elif line[0] == "tagon":
#add a start xml tag, with attributes for the given tkinter tag
name = 'font'
attrib = ""
tag = #the dictionary you stored in your program when creating this tag
for key in tag:
attrib += "%s='%s' "%(key, escape(tag[key]))
output += "<%s %s>"%(name, attrib)
elif line[0] == "tagoff":
#add a closing xml tag
output += '</%s>'%name
How may I change the text in a RaphaelJS-created text node? First, I am creating a new element with a text string with Raphael, and at some later point I would like to change this text. It's easier for me if I do not have to reinitialize the element as there will be a whole host of attributes attached that will be a pain to recreate. Is there a way to do this? I've got my logic below, but it doesn't work; it's there just to provide extra insight as to what I'm trying to achieve.
Thanks
var R = Raphael("graph-o-matic", 1000, 1000);
var title = R.text( 10, 10, 'original text');
...
title.text.innerHTML = 'nifty new text here';
Try this:
title.attr({text: 'nifty new text here'});