XSLFTextRun definition

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

XSLFTextRun definition

giazo
Hey all,

I'm currently working on a tool that is required, between other things, to
fill some XSLFAutoShapes containing placeholder text with actual text,
inside a pptx file.
I'd like to be able to apply the formatting (font
color/size/bold/italic/underlined) of the placeholder to the actual text
that will replace it.
I'm having partial success: while getting the aforementioned textRun
properties isn't a problem, the XSLFTextRun itself seems to vary: the text
it contains is not the text I expect it to contain.

I am working under the assumption that a XSLFTextRun is a String of chars
which share the same set of formatting properties and doesn't contain any
newlines.
Is there an official definition of what a XSLFTextRun is?

I found a StackOverflow post where someone was replying that XSLFTextRun are
somewhat decided by the office suite that generated the pptx/docx/xslx, but
I can't find it now for the life of me. I got it bookmarked on my machine at
my workplace, but I cannot access it remotely, so I'll be able to retrieve
it only just monday.
In the meanwhile I'd like to start thinking to a different solution, if this
turns out to be true.

Thanks in advance

Giacomo


 



--
Sent from: http://apache-poi.1045710.n5.nabble.com/POI-User-f2280730.html

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: XSLFTextRun definition

kiwiwings
Hi Giacomo,

> the text it contains is not the text I expect it to contain
If you would provide your expected text + the file, that would lift the mysterious curtain ... :)

> Is there an official definition of what a XSLFTextRun is?
The official POI statement is in the code ... just look at the hierarchy of XSLFTextRun +
XSLFTextParagraph constructor. When I've refactored the code a while ago, I've tried to
unify HSLF and XSLF usage, therefore the underlying xml structures aren't always
identical to the usermodel classes. I also wouldn't rule out, that eventually I need to
add further classes to handle CTText* classes differently.

> I am working under the assumption that a XSLFTextRun is a String of chars
> which share the same set of formatting properties and doesn't contain any
> newlines.
XSLFLineBreak extends XSLFTextRun ... so your assumption is partly wrong.


> I found a StackOverflow post where someone was replying that XSLFTextRun are
> somewhat decided by the office suite that generated the pptx/docx/xslx
The underlying CT* classes are from the drawingml schema, which is used also by XSSF/XWPF,
but XSLFTextRun is specific to XSLF - the counterpart would be XSSFTextRun.
Those classes are currently independently developed - which is a pity, but one could argue,
that XSSF is more stable than XSLF.

So back to your original problem:

> I'd like to be able to apply the formatting ... of the placeholder to the actual text
> that will replace it.
There are several indirections of the formatting (directly on the XSLFTextRun, inherited by the
slidelayout or the slidemaster, or inherited by the theme) - the easiest would be, if you create
an example file with Powerpoint and then check where your modifications are located
(... in the xmls in the .pptx/.zip)

Sorry to be so unspecific, but your description was also a bit vague ...

Andi




signature.asc (499 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: XSLFTextRun definition

paoim101084
Do you know to add custom font to XSLFTextRun?
For example, I have font file with extension '.ttf'.

Currently, I did like this:
XSLFTextParagraph p =...
XSLFTextRun r = p.addNewTextRun();
r.setFontFamily("input/myfont.ttf");

Please advise?





--
Sent from: http://apache-poi.1045710.n5.nabble.com/POI-User-f2280730.html

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: XSLFTextRun definition

kiwiwings
- You need to register font first - just google for "GraphicsEnvironment registerFont"
https://stackoverflow.com/search?q=%5Bjava%5D+GraphicsEnvironment+registerFont

- then simply set the font name as font family


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: XSLFTextRun definition

paoim101084
1. Register Font
Font font = Font.createFont(Font.TRUETYPE_FONT, new
File("input/myfont.ttf"));
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(font);
String[] names = ge.getAvailableFontFamilyNames();
2. Set font name as font family:
XSLFTextParagraph p =...
XSLFTextRun r = p.addNewTextRun();
for (String name : names) {
   r.setFontFamily(name);
}

Will support all available font family or just get the last one of Array?



--
Sent from: http://apache-poi.1045710.n5.nabble.com/POI-User-f2280730.html

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: XSLFTextRun definition

kiwiwings
On 18.12.18 20:47, paoim101084 wrote:
> Will support all available font family or just get the last one of Array?

Although you could easily try that yourself, before posting in the mailing list - the answer is: "it depends", not all font families can be used in Powerpoint - I would only use True-Type-Fonts and maybe Open-Type-Fonts, not bitmap fonts. This also depends what is available on your client PC systems, so I would use the usual suspects like "Arial", "Courier New" - there is also a font substitution available in Powerpoint, but that goes a bit beyond the scope now.

Registering the font family is only necessary if you want to calculate the table height, because internally the table is rendered to pixels. So outside of your use case you can specify any font family you like.

It's also possible to provide embedded fonts and I have an outdated implementation for this in [1], but there are some drawbacks [2].



[1] https://github.com/kiwiwings/pptx-shape-exporter

[2]
https://stackoverflow.com/questions/47920767/how-to-add-custom-fonts-in-apache-poi-ppt
https://mail-archives.apache.org/mod_mbox/poi-user/201310.mbox/%3C525B017B.90804@...%3E



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: XSLFTextRun definition

paoim101084
Hi Andi,

Thank for your detail information.

Yes, I want to calculate the table height.
Could you help to provide some idea about that?

Here is what I did but it seems not work well:
static void calculateTableHeight(XSLFTable tab, Rectangle2D anchor) {//FIXME
- issue?
                double totalCellAnchorHeight = 0;
                for (XSLFTableRow row : tab.getRows()) {
                        /*for (XSLFTableCell cell : row.getCells()) {
                                cell.resizeToFitText(); //make Cell Height fits with Text Height
                        }*/
                        List<Double> cellAnchorHeightList = row.getCells().stream().map(c ->
c.getAnchor().getHeight()).collect(Collectors.toList());
                        double maxCellAnchorHeight = Collections.max(cellAnchorHeightList);// Get
only Max Cell Anchor's height
                        totalCellAnchorHeight += maxCellAnchorHeight;
                }
                Rectangle2D newAnchor = new Rectangle2D.Double(anchor.getX(),
anchor.getY(), anchor.getWidth(), totalCellAnchorHeight);
                tab.setAnchor(newAnchor);
        }



--
Sent from: http://apache-poi.1045710.n5.nabble.com/POI-User-f2280730.html

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: XSLFTextRun definition

kiwiwings
I've applied a patch via #63017 [1]

So have a look at [2] at method testResize().
This should be somehow what you want - add rows until a max size is reached and then
continue on the next page.

The dimensions are only approx. correct - hence I've added the rendering via PPTX2PNG -
which you might need to activate (set format to "png") - to show how the renderer behaves.
This differs how the table is displayed in (Libre) Office, but should be good enough for your use case.


[1] https://bz.apache.org/bugzilla/show_bug.cgi?id=63017
[2] https://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java?view=markup&pathrev=1849244

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: XSLFTextRun definition

paoim101084
Hi Andi,

When will be available for those updated?

For 4.x.x version, I cannot find these methods:

XSLFTable tab =...
tab.removeRow(.)
tab.updateCellAnchor()
...

Anywhere, thank for those things.

Well, great if *XSLFTable* or *Slide* can know if /content/ fits with one
*slide* and then /remaining content/ will display to *next slide*.


Thanks





--
Sent from: http://apache-poi.1045710.n5.nabble.com/POI-User-f2280730.html

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: XSLFTextRun definition

kiwiwings
HI,

the modifications are in the trunk - so if you want it immediately, you could use a nightly [1].
The next release of POI (4.1.0) will be around end of February.

> Well, great if *XSLFTable* or *Slide* can know if /content/ fits with one
> *slide* and then /remaining content/ will display to *next slide*.
XSLFTable doesn't know what you are up to ... you have to ask for its height and decide,
if you want to skip to the next slide - that's what the testResize() test is doing.

Andi



[1] https://builds.apache.org/view/P/view/POI/job/POI-DSL-1.8/lastSuccessfulBuild/artifact/build/dist/



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: XSLFTextRun definition

paoim101084
Hi Andi,

I have used a nightly [1] and run your program [2], I found description
displays out of red bordered box.
I think calculation of:
XSLFSlide slide =...
// a red bordered box in the background, to show/verify the table dimensions
XSLFAutoShape as = slide.createAutoShape();
as.setShapeType(ShapeType.RECT);
as.setStrokeStyle(Color.RED, 2., StrokeStyle.LineDash.LG_DASH);

XSLFTable tab = slide.createTable(1, data[0].length);
....
tab.updateCellAnchor();
....

tab.updateCellAnchor();
as.setAnchor(tab.getAnchor());

It seems not work well. It should calculate the text wrapping too.
You can look at image in attachment.
<http://apache-poi.1045710.n5.nabble.com/file/t340639/updateCellAnchor_result.png>


[1]
https://builds.apache.org/view/P/view/POI/job/POI-DSL-1.8/lastSuccessfulBuild/artifact/build/dist/
[2]
https://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java?view=markup&pathrev=1849244



--
Sent from: http://apache-poi.1045710.n5.nabble.com/POI-User-f2280730.html

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: XSLFTextRun definition

kiwiwings
Was the slide screenshot rendered by POI (with PPTX2PNG) or did you export
the slide as Png from Powerpoint?

I'm asking as I was of course testing/rendering the output and POIs pngs had
the red box around the content. And I also noted, that the calculation is
sub optimal and doesn't match the results of PowerPoint 1:1, but for the
sake of table breaking it should be enough.

In case this is happening with POIs PPTX2PNG rendering, I'm a bit clueless
currently. To minimize side effects and find the error, we need to narrow
the example, I.e. provide the fonts, define the Java version/runtime and the
operating system (Linux/Windows - no Mac)

Andi



--
Sent from: http://apache-poi.1045710.n5.nabble.com/POI-User-f2280730.html

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: XSLFTextRun definition

paoim101084
Hi Andi,

I am so happy because we can render table into different slides.
Thanks for your efforts.


Here is what I have:
1. Java 1.8
2. Use system font - I did not change
3. Operating system: window 10

Sorry, I just make the code can run like this:

import java.awt.Color;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Random;

import org.apache.poi.sl.usermodel.ShapeType;
import org.apache.poi.sl.usermodel.StrokeStyle;
import org.apache.poi.util.TempFile;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFAutoShape;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xslf.usermodel.XSLFTable;
import org.apache.poi.xslf.usermodel.XSLFTableRow;
import org.apache.poi.xslf.usermodel.XSLFTextRun;
import org.apache.poi.xslf.util.PPTX2PNG;

public class XSLFTableFirstDemo {

    private static String[][] getDummyData(int rows) {
        String[] header = { "Row#", "ID", "Name", "Description", "Price",
"Percent", "Current Value" };
        String[][] data = new String[rows+1][header.length];
        System.arraycopy(header, 0, data[0], 0, header.length);

        String[] names = { "car", "rubber duckie", "phone", "gadget" };
        String[] desc = { "new", "used", "untouched" };

        Random r = new Random();

        for (int row=1; row<=rows; row++) {
            String[] line = new String[header.length];
            line[0] = Integer.toString(row);
            line[1] = Integer.toString(r.nextInt(1000));
            line[2] = names[r.nextInt(names.length)];
            line[3] = "The "+desc[r.nextInt(desc.length)]+" "+line[2]+" in
"+(2017+row);
            line[4] = "$"+r.nextInt(50000);
            line[5] = r.nextInt(100)+"%";
            line[6] = "$"+r.nextInt(50000);
            System.arraycopy(line, 0, data[row], 0, header.length);
        }

        return data;
    }

        public static void main(String[] args) throws Exception {
                String[][] data = getDummyData(20);
        final int maxHeight = 400;

        XMLSlideShow ppt = new XMLSlideShow();
       
        int rowIdx=1;
        while (rowIdx<data.length) {
            XSLFSlide slide = ppt.createSlide();
            // a red bordered box in the background, to show/verify the
table dimensions
            XSLFAutoShape as = slide.createAutoShape();
            as.setShapeType(ShapeType.RECT);
            as.setStrokeStyle(Color.RED, 2., StrokeStyle.LineDash.LG_DASH);

            XSLFTable tab = slide.createTable(1, data[0].length);
            tab.setAnchor(new Rectangle2D.Double(50,50,0,0));
            tab.setColumnWidth(0, 60);
            tab.setColumnWidth(1, 60);
            tab.setColumnWidth(2, 60);

                        int startRow = rowIdx - 1;

            XSLFTableRow row = tab.getRows().get(0);
            for (int colIdx=0; colIdx&lt;data[0].length; colIdx++) {
                XSLFTextRun tr =
row.getCells().get(colIdx).setText(data[0][colIdx]);
                tr.setFontSize(20.);
                tr.setFontFamily(&quot;Arial&quot;);
            }


                        while (rowIdx &lt; data.length) {
                row = tab.addRow();
                for (int col=0; col&lt;data[rowIdx].length; col++) {
                    XSLFTextRun tr =
row.addCell().setText(data[rowIdx][col]);
                    tr.setFontSize(15.);
                    tr.setFontFamily(&quot;Arial&quot;);
                }
                tab.updateCellAnchor();
                if (tab.getAnchor().getHeight() > maxHeight) {
                                        tab.removeRow(rowIdx - startRow);
                    break;
                }
                rowIdx++;
            }

            tab.updateCellAnchor();
            as.setAnchor(tab.getAnchor());
        }
       
        File fileOut = TempFile.createTempFile("xslfTableDemo", ".pptx");
        try (FileOutputStream fos = new FileOutputStream(fileOut)) {
            ppt.write(fos);
        }

        String[] arguments = {
            "-format", "null", // png,gif,jpg or null for test
            "-slide", "-1", // -1 for all
            "-outdir", fileOut.getParentFile().getCanonicalPath(),
            "-quiet",
            fileOut.getAbsolutePath()
        };
        PPTX2PNG.main(arguments);
        }
}

When I run it, I open xslfTableDemo.pptx, I found the description wraps out
of border.
You know, what I did, I got the same issue too.
If we can fix that, it is so awesome.





--
Sent from: http://apache-poi.1045710.n5.nabble.com/POI-User-f2280730.html

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: XSLFTextRun definition

kiwiwings
"-format", "null"  ... means there wasn't any rendering of POI saved to disc.
And you wrote you've opened the xslfTableDemo.pptx in PowerPoint and the
description was out of bounds.

The problem with text rendering is, ...
* that POI doesn't know about hyphenation
* the linebreak calculation of AWT is different to Office
* the line spacing is slightly different
* sometimes also the resolution of your desktop has side effects
* and on which operating system you execute the test - Macs for instance
have some strange font handling with certain fonts

Therefore I can't provide you a solution which accurately calculate the
bounding box - if someone else knows some tricks to be more accurate and
platform independent, have a look at [3] for test set.

So you need to work with that inaccuracy and use some space below the table
before you continue with further text.
... and remove that red border ;)

Andi



[3]
https://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/sl/TestFonts.java?view=markup



--
Sent from: http://apache-poi.1045710.n5.nabble.com/POI-User-f2280730.html

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: XSLFTextRun definition

paoim101084
Hi Andi,

Thank for providing more details.
Well, I am looking forward to getting new release on February.

Thanks



--
Sent from: http://apache-poi.1045710.n5.nabble.com/POI-User-f2280730.html

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]