Obtaining an Apache POI XSSFRichTextString from a textbox - java

How do I get an XSSFRichTextString from an Textbox in an excel spreadsheet using POI?
The setText() method is overloaded to set either a String or XSSFRichTextString but the getText() method only returns a String.
My approaches were as follows:-
Change just the text in the textbox but leave the formatting unchanged. I was hoping to get the string and simply change the text but there seems to be no setText method in XSSFRichTextString. It appears that you set the text in the constructor then apply formatting using methods. Using this does put the text in the textbox but it loses all formatting.
Extract the entire XSSFRichTextString, extract the Formatting, create a new RTS with the new text and apply the formatting. The problem is that while there is a setFont(Font object) method the getFont() returns only a short so I cannot seem to get the Font object and change it.
3 My last option is to set the plain text in the Textbox and then programmatically set all the font and formatting elements but this means burying the formatting in the Java code which means re-coding if the user needs to tweak the format instead of just using Excel.
Any suggestions?

Promoting some comments to an answer
You can't get a RichTextString from an Excel textbox. The storage model for formatted text in a textbox was changed from that in plain cells, mostly it seems to support extra features and kinds of formatting. Textbox text is a bit more Word-like in how it's structured / stored
However, there's good news - you can do what you want, and change some specific text in a textbox without changing the formatting!
Firstly, from your XSSFTextBox, call getTextParagraphs() to get the paragraphs
Next, call getTextRuns() to get the individual runs of text sharing the same formatting. Search through those until you find the one(s) containing the text you want to change. Finally, call XSSFTextRun.setText(String) to change the text of that run. The formatting will be unchanged

Related

Use iText to produce formatted TextFields?

Is there any way in iText to format a TextField's input? I want to have a TextField accept a phone number "(###)###-####", but I don't want the user to have to format it when they enter it. Pdf supports masks on form fields, is there any way to do this in iText?
My current solution is to create the pdf in Acrobat, then populate known fields through iText. But that isn't ideal for this deployment. Ideally I'll have iText generate the entire form.
Thanks for all assistance in advance.
You can add JavaScript to your form that changes the content of fields. See for instance the Calculator example for a fun PDF that acts as a Calculator (obviously this app only works in a PDF viewer that supports JavaScript).
When you create a text field, you need to add an additional action with the setAdditionalActions() method. You can choose between different events: K for keystroke (e.g. useful if you want to change every character to uppercase when somebody fills out a form), Bl for blurred (useful to process the content of a field as soon as the focus is lost), etc.
You can write your own document-level JavaScript to format the fields. See calculator.js for the JavaScript used in the Calculator example. Or you can use one of the many AF methods that are predefined Adobe Reader, such as AFNumber_Format (I don't find an overview of the available methods right now).

Find invisible text in iText

I am creating a PDF document of multiple pages using iText. I am adding some unique text on one of the pages in the middle of this document but making it invisible as-
Chunk chunk = new Chunk("invisible text here");
chunk.setTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_INVISIBLE, 0f, null);
com.lowagie.text.Document iTextDoc.add(new Paragraph(Element.ALIGN_JUSTIFIED, chunk));
The reason for adding this invisible text is to identify this particular page at the time of onEndPage(). But it is failing.
To achieve in the onEndPage(), I have the following code -
boolean b = (pdfWriter.getDirectContent().toString()).contains("invisible text here");
I get the value of b as false.
If I compare any other text on that page(which is visible) results b as true.
I tried to manually search the invisible text in the PDF reader and it finds the text.
What could I modify to achieve this?
It is never a good idea to assume you can recognize text in the content without elaborate parsing. The text may be split into multiple segments, encoding might not be platform's default character encoding, etc... Thus don't try something like
boolean b = (pdfWriter.getDirectContent().toString()).contains("invisible text here");
You can achieve your goal
The reason for adding this invisible text is to identify this particular page at the time of onEndPage().
much more easily. Simply add a member to your PdfPageEvent implementation, i.e. the class with your onEndPage() method, and set it where you used to add the invisible page content to the text you used to add to the page.
Now you can test that member variable directly in your onEndPage(). Don't forget to reset the variable afterwards, preferably in onEndPage() itself!

Getting style from any offset in JTextPane

Is there a way to get Style, a style name or just even compare whether Style at a certain position of JTextPane with the style I gave the text when inserting? Because for my purpose I created custom JTextPane, StyledDocument and DocumentFilter. So I could choose Style to be used for say regular letters and another Style for numbers. I have also toggle button which while toggled sets DocumentFilter to format numbers differently and while not toggled numbers format regularly so at the end you can't distinguish which numbers have been affected just according to JTextPane's getText() method. Therefore the only way would be to compare styles which I have both regular and special number style as constants. Only thing I need to come up with is how to get Style for each character.
I know there is JTextPane's method to get AttributeSet from the caret's position called getCharacterAttributes() but I think it's no use for my issue.
Is it necessary to include code example? I don't think it's difficult to imagine. If you want me I will include it though.
Any input would be appreciated. Thanks!
Try calling StyledDocument.getCharacterElement(pos) to get the character element at that position and then call Element.getAttributes() to get its attribute set.
The AttributeSet contains styles which you can retrieve using methods provided by StyleConstants.

Making words different colors in JTextField/JTextPane/?

I'm trying and failing to understand how to use Java's text editor components to colorize text as you insert it. I don't want or need a fully featured syntax highlighting library.
Basically, I have a JTextField (or some other JText... component), and a list of words. I want any words in the field that appear in the list to be red, and the rest of the words be green. So for example, if "fire" is in the list, "fir" would appear green and "fire" would appear red.
I've tried using a JTextPane and a DefaultStyledDocument, using a KeyListener to go over the text in the document and using AbstractStyledDocument.replace to replace the existing words with versions that have the correct attributes. This didn't do anything. What am I doing wrong?
Neither JTextPane nor JTextField isn't able to present formatted text, i.e text having more than one format. For text-editor-like capabilities like you'd find in WordPad or HTML, the component to use is the JEditorPane or its descendant, JTextPane.
The simplest thing you can do is set the ContentType of the JEditorPane to "text/html" and simply set its text to a string containing HTML. The Java structured text components are surprisingly competent with HTML; you can display tables and/or DIVs, and there is support for much of CSS2. Simplest to do your styles inline, but you can even do external style hrefs.
If you want to get fancy programmatically, you can access the DocumentModel and create text from spans of text each having their own formatting. The DocumentModel works essentially like a programmable text editor.
EDIT: Re-reading your question, I see my answer doesn't quite address it. Since you want multi-colored text JEditorPane is your only option; but rather than just piping in pre-colored text via HTML or such, you'll have to put a listener on your document model to catch changes introduced when you type; and after every document change you'll want to examine the text (again from the Document model) for text that should or should not be highlighted, and you'll want to apply formatting to certain runs of text.
There are devils in the details, but this should get you started.

Selecting specified text in an HTML formatted JEditorPane

I am displaying text in a Java JEditorPane using HTML to fomrat the text. I am also designing a search function that finds text in the JEditorPane selects the text and then scrolls to it. My problem is creating an algorithim that will actually specify the beginning and ending position for the selection.
If I simply retrieve the text using myeditorpane.getText(), then find the search string in the result, the wrong selection start and end positions are calculated with the wrong text being selected (the tags are throwing the calculation off). I tried removing the html tags by executing a replace all function text.().replaceAll("\<.*?>","") before searching for the text (this replace all removes all text in between the tags) but still the wrong selection points are calculated (although I'm getting close :-)).
Does anyone have an easy way to do this?
Thanks,
Elliott
You probably want to be working with the underlying Document, rather than the raw text, as suggested in this HighlightExample.
You need to find the start location of the text. I guess something like:
int offset = editorPane().getDocument().getText().indexof(...);
Then to scroll you can use:
editorPane.scrollRectToVisible( editorPane.viewToModel(offset) );
Read up on Text and New Lines for more info.

Categories