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?
Related
Existing requirements: search for the specified text in the pdf file, replace the specified text, and record the page, row and column where the modified text is located.
I am using the spire jar package, which has implemented search and replacement. The number of pages can be recorded with api, but I don't know how to record the rows and columns. There are many on the website that use the coordinate method to locate.
public static void main(String[] args) {
//加载示例PDF文档
PdfDocument pdf = new PdfDocument();
pdf.loadFromFile("D:\\Spire\\Input\\test05.pdf");
//遍历文档
for (int i = 0; i < pdf.getPages().getCount(); i++)
{
//获取所有页面
PdfPageBase page = pdf.getPages().get(i);
//查找指定文本
PdfTextFindCollection textFindCollection;
textFindCollection = page.findText("内容提要");
//创建画刷、字体
PdfSolidBrush brush = new PdfSolidBrush(new PdfRGBColor(Color.red));
PdfTrueTypeFont font= new PdfTrueTypeFont(new Font("宋体",Font.PLAIN,12),true);
//用新的文本替换原有文本
Rectangle2D rec;
for(PdfTextFind find: textFindCollection.getFinds())
{
rec = find.getBounds();
System.out.println(rec);
page.getCanvas().drawRectangle(PdfBrushes.getWhite(), rec);
page.getCanvas().drawString("Coffee", font, brush, rec);
}
}
//保存文档
pdf.saveToFile("D:\\Spire\\OutPut\\Replace.pdf");
pdf.close();
}
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);
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.
I have a JEditorPane that displays a link containing an image like so:
<a href='http://somesite.com/'>
<img src='someImage.png' />
</a>
When the JEditorPane display this as HTML, it puts a blue border around the image which I am trying to remove without any luck.
I want it to look like this inside of the jeditorpane:
image: (http://randomcloud.net/img/prob/valid.png)
But this is how the JEditorPane displays it:
image(http://randomcloud.net/img/prob/jeditorpane.png)
This is what I have tried so far, and it still is not working
editorPane = new JEditorPane("http://randomcloud.net/ads/index.php?id=1");
StyleSheet style = ((HTMLDocument)editorPane.getDocument()).getStyleSheet();
style.addRule("a img {text-decoration: none; border: none;}");
Any suggestions or insight ?
-Michel
HTLEditorKit's ImageView source. As you can see borderSize is set to DEFAULT_BORDER (2 pixels). You can replace the ImageView creation in your implementation of ViewFactory and override the method to provide desired border (0 as I understand).
protected void setPropertiesFromAttributes() {
StyleSheet sheet = getStyleSheet();
this.attr = sheet.getViewAttributes(this);
// Gutters
borderSize = (short)getIntAttr(HTML.Attribute.BORDER, isLink() ?
DEFAULT_BORDER : 0);
leftInset = rightInset = (short)(getIntAttr(HTML.Attribute.HSPACE,
0) + borderSize);
topInset = bottomInset = (short)(getIntAttr(HTML.Attribute.VSPACE,
0) + borderSize);
borderColor = ((StyledDocument)getDocument()).getForeground
(getAttributes());
AttributeSet attr = getElement().getAttributes();
// Alignment.
// PENDING: This needs to be changed to support the CSS versions
// when conversion from ALIGN to VERTICAL_ALIGN is complete.
Object alignment = attr.getAttribute(HTML.Attribute.ALIGN);
vAlign = 1.0f;
if (alignment != null) {
alignment = alignment.toString();
if ("top".equals(alignment)) {
vAlign = 0f;
}
else if ("middle".equals(alignment)) {
vAlign = .5f;
}
}
AttributeSet anchorAttr = (AttributeSet)attr.getAttribute(HTML.Tag.A);
if (anchorAttr != null && anchorAttr.isDefined
(HTML.Attribute.HREF)) {
synchronized(this) {
state |= LINK_FLAG;
}
}
else {
synchronized(this) {
state = (state | LINK_FLAG) ^ LINK_FLAG;
}
}
}
I think the blue border is just selection of text. Try to deselect the content or use jEditorPaneInstance.getCaret().setSelectionVisible(false);
#Alien595: On img tags, you can add an attribute named border that is 0.
Example:
<a href="your_link.html">
<img border="0" src="your_image.png"/>
</a>