How to duplicate a slide containing a chart using apache POI? - java

Dear all,
I'm working with Apache POI and I would like to duplicate a slide containing several charts from code.
The code below (inspired by https://poi.apache.org/slideshow/xslf-cookbook.html#Merge) works fine when there is no chart on the slide.
Unfortunately, it seems that the charts are not duplicated with this method: when I try to open the resulting file, Powerpoint detects a problem, tries to repair it, but fails, and I get empty slides.
I've checked the underlying XML files (using Open XML SDK), and it seems that the chart themselves (in the folder /ppt/charts) are not duplicated, and the relationship files (in the folder /ppt/slides/_rels) are not completely updated.
Here is my current code:
// Open slideshow
FileInputStream fileInputStream = new FileInputStream(sourceFilePath);
XMLSlideShow slideShow = new XMLSlideShow(fileInputStream);
fileInputStream.close();
// Duplicate slide
XSLFSlideLayout layout = slide.getSlideLayout();
XSLFSlide newSlide = slideshow.createSlide(layout);
newSlide.importContent(slide);
// Save updated slideshow
FileOutputStream fileOutputStream = new FileOutputStream(outputFilePath);
slideShow.write(fileOutputStream);
fileOutputStream.close();
Do you know how I could clone a slide and its charts ?
Thanks a lot, and best regards!

You can't. I tried and tried, the problem is that the duplication does not handle images or charts.
I had to copy files by hand through a script. Here are the steps:
Locate the slide file
Duplicate it
Find the chart object in the XML file, and note the relation Id
In the relations file, check which file is designated by the relation Id
Duplicate this file
You also have to duplicate the relation file for the new slide, and update the name
The new slide is not visible, you have to update presentaion.xml
Please note: if you want your PPTX to work with Microsoft Powerpoint, you'll also have to duplicate associated Excel workbook (see in the relation file of the chart)

My problem was really close to yours with version 5.2.2, the chart was indeed correctly duplicated but the reference to the internal workbook of the sheet was copied too, by reference ! (It's actually done here : https://apache.googlesource.com/poi/+/refs/tags/REL_5_2_2/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFGraphicFrame.java#241 )
It means that when I edited the chart values in the duplicated slide I edited both chart values. It makes visually no difference in powerpoint at first but when you right-click>edit data on the chart, it re-renders and the data changes visually.
To avoid that, just re-set the workbook of the chart to null so that it creates (or really load from the relation part) a new one for the duplicated chart
The code to duplicate a slide with a chart should look like this :
XSLFSlide oldSlide = ppt.getSlides().get(number);
XSLFSlideLayout layout = oldSlide.getSlideLayout();
XSLFSlide newSlide = ppt.createSlide(layout);
newSlide.importContent(oldSlide);
newSlide.getRelations().stream()
.filter(r -> r instanceof XSLFChart)
.forEach(chart->((XSLFChart)chart).setWorkbook(null));
//to force loading the correct worksheet
I hope it help some people stumbling upon this :)

Since Apache POI 4.0.0, the original code from the question will work to duplicate a slide.

Related

Pivot table refresh and save code in aspose cells for java corrupts excel file

I am using aspose-cells-8.7.2-java. When I refresh the pivot table and save it, the excel file is getting corrupted. When I try to open the excel file I am getting the alert message as below :
"Excel found unreadable content in 'Book1.xlsx'.Do you want to recover the contents of this workbook?If you trust the source file of this workbook, click yes."
The code is as below :
Workbook wb = new Workbook("Book1.xlsx");
PivotTable pt = wb.getWorksheets().get(1).getPivotTables().get(0);
pt.refreshData();
pt.calculateData();
wb.save("Book1.xlsx");
Any help ?
I found this thread where the same issue is logged as a ticket :
http://www.aspose.com/community/forums/thread/683715/aspose.cells-generates-a-corrupted-xlsx-file-excel-2007-fails-to-open.aspx.
Is this issue solved?
I'm afraid the logged issue is not resolved yet. By the way, do you use similar Excel file or yours template file "Book1.xlsx" is different. Moreover, your issue can be template specific (if you are using different file) and might have different scenarios, so we need your template "Book1.xlsx" file to properly evaluate your issue on our end. We recommend you to kindly create a separate thread in Aspose.Cells forum with your template Excel file, we will evaluate your issue and help you better there.
I am working as Support developer/ Evangelist at Aspose.

How to extract data from a .docx file including image, table, formula etc?

I am doing a task in which i have to extract data from word document mainly images, tables and special texts(formula etc) .
I am able to save image from a word file it is downloaded from web but when i am applying same code to my .docx file than it is giving error.
Code for same is
//create file inputstream to read from a binary file
FileInputStream fs=new FileInputStream(filename);
//create office word 2007+ document object to wrap the word file
XWPFDocument docx=new XWPFDocument(fs);
//get all images from the document and store them in the list piclist
List<XWPFPictureData> piclist=docx.getAllPictures();
//traverse through the list and write each image to a file
Iterator<XWPFPictureData> iterator=piclist.iterator();
System.out.println(piclist.size());
while(iterator.hasNext()){
XWPFPictureData pic=iterator.next();
byte[] bytepic=pic.getData();
int i=0;
BufferedImage imag=ImageIO.read(new ByteArrayInputStream(bytepic));
//captureimage(imag,i,flag,j);
if(imag != null)
{
ImageIO.write(imag, "jpg", new File("D:/imagefromword"+i+".jpg"));
}else{
System.out.println("imag is empty");
}
It is giving incorrect format error. But I cannot change the doc file.
Secondly for above code if i am having more then one image and when i am saving this than every time it saving save image. Suppose we have 3 images then it will save 3 images but all three will be latest one.
Any help will be appreciated.
Without actual error one can only guess.
But there are two POI implementations HWPF and XWPF depending which version of word document your read the old doc one or xml-new-one docx. Typically the format error comes when you try to open the doc using the wrong one.
Also you need the full poi-ooxml-schemas jar to read more complicated documents.

Creating a hyperlink using apache poi

I am trying to create a hyperlink using the following code
CreationHelper createHelper = wb.getCreationHelper();
cell.setCellValue("Click Here");
Hyperlink link = createHelper.createHyperlink(Hyperlink.LINK_FILE);
File f = new File("C:\\Test\\1.pdf");
link.setAddress(f.getCanonicalPath());
cell.setHyperlink((org.apache.poi.ss.usermodel.Hyperlink) link);
It works fine and it adds a link Click Here to the cell
But how i can set a partial text and a link using same type of code, I mean the link need to be like your file is here, where only here is the link
As far as I know I don't think it is possible, as it is not supported by Excel as well. To achieve that in Excel too there is no straight way and you have to do some tricks to achieve that. Something that is not supported right from Excel cannot be supported by Apache POI too.

jasperreports: can see background image in pdf export but not in docx export

Report generation:
The following code resides in a servlet and generates both a "letter.docx" word document to download and a "pika.pdf" file in C:
I am able to see the background image i defined in pika, but not in "letter".
InputStream is = request.getServletContext().getResourceAsStream("/resources/reports/" +name);
JasperReport jr = JasperCompileManager.compileReport(is);
JasperPrint jp = JasperFillManager.fillReport(jr, params, ds);
JRExporter exp = new JRDocxExporter();
exp.setParameter(JRExporterParameter.JASPER_PRINT, jp);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
exp.setParameter(JRExporterParameter.OUTPUT_STREAM, bos);
exp.exportReport();
JasperExportManager.exportReportToPdfFile(jp, "C:\\pika.pdf");
byte[] bytes = bos.toByteArray();
response.reset();
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition", "attachment; filename=\"letter.docx\"");
response.getOutputStream().write(bytes);
response.getOutputStream().flush();
response.getOutputStream().close();
Looking for an answer in the jasper community, i can see you are not the first one that asked by this.
Here is another question like yours all says that you can't set an image as background in doc reports.
The last things i found in my travel are three alternatives:
JOD Reports The most radical option, if you can change you report engine, check this out.
Other tutorial that shows how to embed images, but i'm not sure that works in Word docs specific case.
The last tutorial Here in SO, a little taste to put text as background.
Hope this helps, cheers.
I don't have enough information on your case but once I had a very nasty problem with Excel export, a cell wasn't being shown in XLS but in PDF it was shown fine. What I found out was just a single pixel misalignment between the header band and value band for the same column. This brought an extra cell into each of the values rows and JR couldn't populate it correctly.
So checking for misalignments in the JRXML is my advice, based upon previous experiences. Since MS Office formats are not well standardized as PDF or HTML, their exporting tends to be more "glitched".
JRDocxExporter is a grid exporter, it generates a table and then populates each cell of this table with the elements in the jasper template.
If an element in the template overlaps another element, the further element does not display, because in a table a cell cannot overlap another cell.

Set page view mode in excel file using apache poi

Excel has different modes for viewing a sheet: Normal, Page Layout, Page Break Preview. (In excel 2010: in the view tab). The view mode is saved seperately for each sheet in a workbook and is restored when opened again.
I am trying to find a way to set a view mode using Either HSSF or XSSF.
In the old binary format, finding the answer seems quite impossible unfortunately.
In 2007+ OOXML format diffing does give the basic answer, looking at xl/worksheets/sheet1.xml
In normal view:
<sheetViews>
<sheetView rightToLeft="1" tabSelected="1" zoomScaleNormal="100" workbookViewId="0">
</sheetViews>
In page layout view:
<sheetViews>
<sheetView rightToLeft="1" tabSelected="1" view="pageLayout" zoomScaleNormal="100" workbookViewId="0"/>
</sheetViews>
That is the second tag in each sheet. Is there any XSSF API option to edit that attribute? (or the only solution to the problem would be unpacking the file, editing it and repacking)
Thanks!
XSSF doesn't expose this directly, but you can get at it if you want
From the XSSFSheet object, call getCTWorksheet to get the low level XML object backing the sheet. CTWorksheet provides a getSheetViews method. You'll like want something like:
CTSheetView view = sheet.getCTWorksheet().getSheetViews().getSheetViewArray(0);
view.setView(STSheetViewType.PAGE_LAYOUT);

Categories

Resources