I have tried creating the new presentation using the existing list of oldPresentations. Now If I am trying to copy the slidemASTER and layout from the oldPresenation file's slide into my new Slide it is breaking the existing layout and masterSlide.
for (SlideInfo slideInfo : req) {
XSLFSlide srcSlide = slidesMap.get(slideInfo.getDocIdentity() + "|" + slideInfo.getId());
XSLFSlide newSlide = newPpt.createSlide();
XSLFTheme srcSlideTheme = srcSlide.getTheme();
XSLFTheme newSlideTheme = newSlide.getTheme();
XSLFBackground srcBackground = srcSlide.getBackground();
XSLFBackground newBackground = newSlide.getBackground();
XSLFSlideMaster srcSlideMaster = srcSlide.getSlideMaster();
XSLFSlideMaster newSlideMaster = newSlide.getSlideMaster();
XSLFSlideLayout srcSlideLayout = srcSlide.getSlideLayout();
XSLFSlideLayout newSlideLayout = newSlide.getSlideLayout();
// Check if the importContent is working fine else catch the ClassCastException for slides with different picture data
try {
newSlideLayout.importContent(srcSlideLayout);
newSlideMaster.importContent(srcSlideMaster);
newBackground.setFillColor(srcBackground.getFillColor());
newSlideTheme.importTheme(srcSlideTheme);
newSlide.importContent(srcSlide);
Related
I'm working with PowerPoint template. I'm trying to fill it with data in specific placeholders. I don't have any problem with placing text:
for (XSLFShape sh : slide.getShapes()) {
String name = sh.getShapeName();
String placeholderName = export.getPlaceholderName();
if (sh instanceof XSLFTextShape && name.equalsIgnoreCase(placeholderName)) {
XSLFTextShape txShape = (XSLFTextShape) sh;
txShape.clearText();
txShape.setText(parsedText);
}
}
I'm not able to add image to existing anchor. What I found is that first I have to collect shape data with anchor
for (XSLFShape sh : slide.getShapes()) {
String name = sh.getShapeName();
String placeholderName = export.getPlaceholderName();
if (sh instanceof XSLFPictureShape) {
XSLFPictureShape shape = (XSLFPictureShape) sh;
String shapeName = shape.getShapeName();
removeShape.setShapeName(shapeName);
removeShape.setAnchor(shape.getAnchor());
removeShape.setShape(shape);
}
}
and then add picture with anchor collected data and remove original.
XSLFPictureData pd = ppt.addPicture(removeShape.getPictureData(), PictureData.PictureType.PNG);
XSLFPictureShape pic = slide.createPicture(pd);
pic.setAnchor(removeShape.getAnchor());
slide.removeShape(removeShape.getShape());
Is there any easier way to add image to placeholder image on template?
I have problem with slide master layout which contains page number and static text. I have them on my layouts but they are not appearing once I'm generating presentation. When I go INSTER --> Page Number I can select and they appear. When I'm adding new slide to my generated presentation via PowerPoint (add slide with selected layout), then it's showing page number for that page.
Here is the code:
String fileName = "slidemaster-010";
String templateLocation = "/Users/akonopko/Export/Templates/Presentation10.pptx";
XMLSlideShow ppt = new XMLSlideShow(new FileInputStream(templateLocation));
XSLFSlideMaster defaultMaster = ppt.getSlideMasters().get(0);
XSLFSlideLayout masterLayout = defaultMaster.getLayout("Master");
XSLFSlide slide = ppt.createSlide(masterLayout);
XSLFSlideLayout masterLayout1 = defaultMaster.getLayout("1_Custom Layout");
XSLFSlide slide2 = ppt.createSlide(masterLayout1);
List<XSLFShape> slideShapes = slide2.getShapes();
for (XSLFShape shape : slideShapes) {
if (shape.getPlaceholder() == Placeholder.TITLE) {
((XSLFTextShape) shape).setText("Test Text");
}
}
Apache POI just does not copy the placeholders from the XSLFSlideLayout while XMLSlideShow.createSlide(XSLFSlideLayout). It uses XSLFSlideLayout.copyLayout(XSLFSlide) and there DATETIME, SLIDE_NUMBER and FOOTER is explicitly excluded.
One could write a method which copies those placeholders from the layout. This could look like so:
public void copyPlaceholdersFromLayout(XSLFSlideLayout layout, XSLFSlide slide) {
for (XSLFShape sh : layout.getShapes()) {
if (sh instanceof XSLFTextShape) {
XSLFTextShape tsh = (XSLFTextShape) sh;
Placeholder ph = tsh.getTextType();
if (ph == null) continue;
switch (ph) {
// these are special and not copied by default
case DATETIME:
case SLIDE_NUMBER:
case FOOTER:
System.out.println(ph);
slide.getXmlObject().getCSld().getSpTree().addNewSp().set(tsh.getXmlObject().copy());
break;
default:
//slide.getSpTree().addNewSp().set(tsh.getXmlObject().copy());
//already done
}
}
}
}
Get called like so:
copyPlaceholdersFromLayout(masterLayout1, slide2);
But there might be a reason why apache poi explicitly excludes this.
Does anyone have an idea how we can add outlines to text (text outline) within powerpoint templates (ppxt) using Apache POI? What I have gathered so far is that the XSLFTextRun class does not have a method to get/ set the text outline for a given run element.
And as such, I could only persist the following font/ text styles:
def fontStyles(textBox: XSLFTextBox, textRun: XSLFTextRun): Unit = {
val fontFamily = textRun.getFontFamily
val fontColor = textRun.getFontColor
val fontSize = textRun.getFontSize
val fontBold = textRun.isBold
val fontItalic = textRun.isItalic
val textAlign = textRun.getParagraph.getTextAlign
textBox.getTextParagraphs.foreach { p =>
p.getTextRuns.foreach { tr =>
tr.setFontFamily(fontFamily)
tr.setFontColor(fontColor)
tr.setFontSize(fontSize)
tr.setBold(fontBold)
tr.setItalic(fontItalic)
tr.getParagraph.setTextAlign(textAlign)
}
}
}
Is it possible to add text outline?
Any assistance/ suggestions would be highly appreciated.
Apache poi uses underlying ooxml-schemas classes. Those are auto generated from Office Open XML standard. So they are more complete than the high level XSLF classes. Of course they are much less convenient.
So if somewhat is not implemented in high level XSLF classes, we can get the underlying CT classes and do it using those. In case of XSLFTextRun we can get the CTRegularTextRun object. Then we can look whether there are run properties already. If not, we add one. Then we look whether there is outline set already. If so, we unset it, because we want set it new. Then we set a new outline. This simply is a line having a special color. That line is represented by CTLineProperties object. So we need to have methods to create that CTLineProperties, to set CTLineProperties to the XSLFTextRun and get CTLineProperties from XSLFTextRun.
Complete example using Java code:
import java.io.FileOutputStream;
import java.io.FileInputStream;
import org.apache.poi.xslf.usermodel.*;
import org.apache.poi.sl.usermodel.*;
import java.awt.Rectangle;
public class PPTXTextRunOutline {
static org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties createSolidFillLineProperties(java.awt.Color color) {
// create new CTLineProperties
org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties lineProperties
= org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties.Factory.newInstance();
// set line solid fill color
lineProperties.addNewSolidFill().addNewSrgbClr().setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()});
return lineProperties;
}
static void setOutline(XSLFTextRun run, org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties lineProperties) {
// get underlying CTRegularTextRun object
org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun ctRegularTextRun
= (org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun)run.getXmlObject();
// Are there run properties already? If not, add one.
if (ctRegularTextRun.getRPr() == null) ctRegularTextRun.addNewRPr();
// Is there outline set already? If so, unset it, because we are creating it new.
if (ctRegularTextRun.getRPr().isSetLn()) ctRegularTextRun.getRPr().unsetLn();
// set a new outline
ctRegularTextRun.getRPr().setLn(lineProperties);
}
static org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties getOutline(XSLFTextRun run) {
// get underlying CTRegularTextRun object
org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun ctRegularTextRun
= (org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun)run.getXmlObject();
// Are there run properties already? If not, return null.
if (ctRegularTextRun.getRPr() == null) return null;
// get outline, may be null
org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties lineProperties = ctRegularTextRun.getRPr().getLn();
// make a copy to avoid orphaned exceptions or value disconnected exception when set to its own XML parent
if (lineProperties != null) lineProperties = (org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties)lineProperties.copy();
return lineProperties;
}
// your method fontStyles taken to Java code
static void fontStyles(XSLFTextRun templateRun, XSLFTextShape textShape) {
String fontFamily = templateRun.getFontFamily();
PaintStyle fontColor = templateRun.getFontColor();
Double fontSize = templateRun.getFontSize();
boolean fontBold = templateRun.isBold();
boolean fontItalic = templateRun.isItalic();
TextParagraph.TextAlign textAlign = templateRun.getParagraph().getTextAlign();
org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties lineProperties = getOutline(templateRun);
for (XSLFTextParagraph paragraph : textShape.getTextParagraphs()) {
for (XSLFTextRun run : paragraph.getTextRuns()) {
run.setFontFamily(fontFamily);
if(run != templateRun) run.setFontColor(fontColor); // set PaintStyle has the issue which I am avoiding by using a copy of the underlying XML
run.setFontSize(fontSize);
run.setBold(fontBold);
run.setItalic(fontItalic);
run.getParagraph().setTextAlign(textAlign);
setOutline(run, lineProperties);
}
}
}
public static void main(String[] args) throws Exception {
XMLSlideShow slideShow = new XMLSlideShow(new FileInputStream("./PPTXIn.pptx"));
XSLFSlide slide = slideShow.getSlides().get(0);
//as in your code, get a template text run and set its font style to all other runs in text shape
if (slide.getShapes().size() > 0) {
XSLFShape shape = slide.getShapes().get(0);
if (shape instanceof XSLFTextShape) {
XSLFTextShape textShape = (XSLFTextShape) shape;
XSLFTextParagraph paragraph = null;
if(textShape.getTextParagraphs().size() > 0) paragraph = textShape.getTextParagraphs().get(0);
if (paragraph != null) {
XSLFTextRun run = null;
if(paragraph.getTextRuns().size() > 0) run = paragraph.getTextRuns().get(0);
if (run != null) {
fontStyles(run, textShape);
}
}
}
}
//new text box having outlined text from scratch
XSLFTextBox textbox = slide.createTextBox();
textbox.setAnchor(new Rectangle(100, 300, 570, 80));
XSLFTextParagraph paragraph = null;
if(textbox.getTextParagraphs().size() > 0) paragraph = textbox.getTextParagraphs().get(0);
if(paragraph == null) paragraph = textbox.addNewTextParagraph();
XSLFTextRun run = paragraph.addNewTextRun();
run.setText("Test text outline");
run.setFontSize(60d);
run.setFontColor(java.awt.Color.YELLOW);
setOutline(run, createSolidFillLineProperties(java.awt.Color.BLUE));
FileOutputStream out = new FileOutputStream("./PPTXOit.pptx");
slideShow.write(out);
out.close();
}
}
Tested and works using current apache poi 5.0.0.
Using OnEndPage, I add a footer to my PDF created with iTextSharp. The footer font gets progressively bolder with each page.
How can I create consistent NORMAL fonts in my footer?
Here is my code:
public override void OnEndPage(PdfWriter writer, Document doc)
{
iTextSharp.text.Image gif = null;
if (FooterImage)
{
if (File.Exists(PathImages))
{
gif = iTextSharp.text.Image.GetInstance(PathImages);
gif.ScaleToFit(75f, 75f);
gif.SetAbsolutePosition(0, 0);
}
}
string sFooter = string.Empty;
if (FooterURL != null && FooterURL.Length > 0)
{
sFooter = FooterURL + " ";
}
if (FooterDate != null && FooterDate.Length > 0)
{
sFooter += FooterDate + " ";
}
if (FooterPage)
{
sFooter += "Page " + doc.PageNumber.ToString();
}
PdfPTable footerTbl = new PdfPTable(1);
footerTbl.TotalWidth = 900;
footerTbl.HorizontalAlignment = Element.ALIGN_CENTER;
Phrase ph = new Phrase(sFooter, FontFactory.GetFont(FontFactory.TIMES, 10, iTextSharp.text.Font.NORMAL));
PdfPCell cell = new PdfPCell(ph);
cell.Border = 0;
cell.PaddingLeft = 10;
footerTbl.AddCell(cell);
if (FooterImage)
{
PdfContentByte cbfoot = writer.DirectContent;
PdfTemplate tpl = cbfoot.CreateTemplate(gif.Width / 5, gif.Height / 5);
tpl.AddImage(gif);
cbfoot.AddTemplate(tpl, doc.PageSize.Width - 100, 10);
}
footerTbl.WriteSelectedRows(0, -1, 10, 30, writer.DirectContent);
}
In the old days, when there wasn't as much choice as today regarding fonts, people used workarounds to create bold fonts. One way to make a font bold, was by adding the same text over and over again at the same position. I think that this is happening to you.
When you use page events correctly, the onEndPage() method is triggered automatically each time a page ends. My guess is that you're doing something very wrong that triggers the onEndPage() many times. Maybe you are called the onEndPage() from your code, maybe you're adding the page event to the writer more than once (and page events are cumulative).
If I have to guess, I would guess that you are doing the latter. My guess is based on the fact that you are using variables such as FooterImage in your onEndPage() method. How are you setting that variable. If you are setting it in the constructor of the page event and you're adding the new page event over and over again to the writer, then you're doing it wrong.
I'm trying to display a list of strings (filenames, to be pedant) inside a GtkTreeView. I'm creating a single column and trying to fill it with a CellRenderText.
//Setup listview
TreeView imageList = (TreeView)gladeBuilder.getObject("imageListTreeView");
TreeViewColumn column = imageList.appendColumn();
DataColumnString imageColumnString = new DataColumnString();
//Fill listview
ListStore listStore = new ListStore(new DataColumnString[]{imageColumnString});
File[] imageFiles = new File("/path/to/files").listFiles();
// For each file:
for (File file : imageFiles) {
TreeIter row = listStore.appendRow(); //add a row
listStore.setValue(row, imageColumnString, file.getName());
}
CellRendererText cellRendererText = new CellRendererText(column);
cellRendererText.setText(imageColumnString);
The program compiles and run without errors, but the list is displayed empty. Someone can help me to find the error(s)?
Add imageList.set_model (listStore) which actually associates your view with the model. This is required or the view will stay empty as it has no model associate unless you specified it in the builder file which I can only guess at this point.