i want to replace the one data.xml file of power point presentation in java using apache API with other file data.xml
For the reference i want to replace the following file with another power point file.
Following is the code i have tried but xml isnt replacing. I have different XML for both files every time i run after replacing using this code
public static void main(String[] args) {
// TODO Auto-generated method stub
final String filename = "C:/Users/skhan/Desktop/game.pptx";
final String filename1 = "C:/Users/skhan/Desktop/globe.pptx";
try {
XMLSlideShow ppt = new XMLSlideShow(new FileInputStream(filename));
OPCPackage pkg = ppt.getPackage();
PackagePart data = pkg.getPart(
PackagingURIHelper.createPartName("/ppt/diagrams/data1.xml"));
InputStream data1Inp = data.getInputStream();
XMLSlideShow ppt1 = new XMLSlideShow(new FileInputStream(filename1));
OPCPackage pkg1 = ppt1.getPackage();
PackagePart data11 = pkg1.getPart(
PackagingURIHelper.createPartName("/ppt/diagrams/data1.xml"));
InputStream data1Inp1 = data11.getInputStream();
String data1String = GetData(data1Inp);
String data2String = GetData(data1Inp1);
//i want to replace here
PrintStream pr = new PrintStream(data.getOutputStream());
pr.print(data2String);
pr.close();
System.out.println("Completed");
} catch (Exception e) {
e.printStackTrace();
}
}
public static String GetData(InputStream input) throws Exception
{
StringBuilder builder = new StringBuilder();
int ch;
while((ch = input.read()) != -1){
builder.append((char)ch);
}
String theString = builder.toString();
return theString;
}
I added the few line after changing in order to save the file.
The XMLSlideShow must write to some file after changing or adding.
File file =new File(filename);
FileOutputStream out = new FileOutputStream(file);
ppt.write(out);
out.close();
Related
I am using POI to delete "enter" in a .doc file (Blank line).
My code below works correctly when the input file is not large (for example, less than 1MB). However, when I deal with large input.doc that is 4mb, the output.doc is not correctly generated. I can not open the file.
Does anyone have better idea to write the big file correctly? Or, is there any other java code that can delete "enter" in a big .doc file? Thank you very much.
package mydoc;
import org.apache.poi.poifs.filesystem.*;
import org.apache.poi.hwpf.*;
import org.apache.poi.hwpf.usermodel.*;
import java.io.*;
public class test {
/*The ASCII of "Enter" is 13*/
private static final short ENTER_ASCII = 13;
public static void main(String[] args){
/* the location of the input file */
String fileName = "D:\\input.doc";
deleteEnter(fileName);
}
public static void deleteEnter(String fileName){
POIFSFileSystem fs = null;
try{
fs = new POIFSFileSystem(new FileInputStream(fileName));
HWPFDocument doc = new HWPFDocument(fs);
Range range = doc.getRange();
for (int i = 0; i < range.numParagraphs(); i++)
{
if (range.getParagraph(i).text().toCharArray()[0]==ENTER_ASCII)
{
range.getParagraph(i).delete();
}
}
FileOutputStream fos = null;
fos = new FileOutputStream(new File("D:\\output.doc"));
doc.write(fos);
fos.flush();
fos.close();
}//end try
catch (Exception e){
e.printStackTrace();
}//end catch
}
}
Depending on your needs you could even use a macro;
You should even be able to use regex like this: "^13{2,}", but that didn't work for me in Word 2010, see http://social.msdn.microsoft.com/Forums/en-US/0d921f97-b59a-48a9-a01a-20fe72f21c19/how-to-remove-blank-lines-?forum=worddev
Sub RemoveBlankLines()
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "^p^p"
.Replacement.Text = "^p"
.MatchWildcards = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
End Sub
Sub RemoveEnters()
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
'^11 or ^l New line
.Text = "^l"
.Replacement.Text = ""
End With
Selection.Find.Execute Replace:=wdReplaceAll
With Selection.Find
'^13 or ^p Carriage return/paragraph mark
.Text = "^p"
.Replacement.Text = ""
End With
Selection.Find.Execute Replace:=wdReplaceAll
End Sub
"enter" is the line separator right ? It's platform dependant so I propose the above solution :
String separator = System.getProperty("line.separator")
file = new File(filename);
FileInputStream fis=new FileInputStream(file.getAbsolutePath());
HWPFDocument document=new HWPFDocument(fis);
extractor = new WordExtractor(document);
String [] fileData = extractor.getParagraphText();
for(int i=0;i<fileData.length;i++){
if(fileData[i] != null)
fileData[i] = fileData[i].replace(separator,"");
}
And then you just have to output fileData in a clean doc file.
I am able to read a DOC file and get its word count, BUT it is wrong.
My code:
public class WordCounter {
public static void main(String[] args) throws Throwable {
processDOC();
}
private static void processDOC() throws Throwable {
File file = new File("/Users/yjiang/Desktop/whatever.doc");
File file2 = new File("/Users/yjiang/Desktop/Test.docx");
File file3 = new File("/Users/yjiang/Desktop/QB Tests 4-14-2014.xls");
File file4 = new File("/Users/yjiang/Desktop/QB Tests 4-14-2014.xlsx");
try {
FileInputStream fs = new FileInputStream(file);
POIFSFileSystem poifsFileSystem = new POIFSFileSystem(fs);
DirectoryEntry directoryEntry = poifsFileSystem.getRoot();
DocumentEntry documentEntry = (DocumentEntry) directoryEntry.getEntry(SummaryInformation.DEFAULT_STREAM_NAME);
DocumentInputStream dis = new DocumentInputStream(documentEntry);
PropertySet ps = new PropertySet(dis);
SummaryInformation si = new SummaryInformation(ps);
System.out.println(si.getWordCount());
} catch (Exception e) {
e.printStackTrace();
}
try {
HWPFDocument hwpfDocument = new HWPFDocument(new FileInputStream(file));
System.out.println(hwpfDocument.getDocProperties().getCWords()); // actually 71 words using word count in MSWord, returned 57.
System.out.println(hwpfDocument.getDocProperties().getCWordsFtnEnd());
XWPFDocument xwpfDocument = new XWPFDocument(new FileInputStream(file2)); // actually 71 words using word count in MSWord, returned 57.
System.out.println(xwpfDocument.getProperties().getExtendedProperties().getUnderlyingProperties().getWords());
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
}
}
"whatever.doc" has 71 words, when I run this, it returns only 57.
Seems I cannot use the same method to read DOCX files, when I run it I get the following:
org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)
Could provide an example?
I've also found that the built-in word counters give strange counts, but text extraction seems to be more reliable, so I use this solution:
public long getWordCount(File file) throws IOException {
POITextExtractor textExtractor;
if (file.getName().endsWith(".docx")) {
XWPFDocument doc = new XWPFDocument(new FileInputStream(file));
textExtractor = new XWPFWordExtractor(doc);
}
else if (file.getName().endsWith(".doc")) {
textExtractor = new WordExtractor(new FileInputStream(file));
}
else {
throw new IllegalArgumentException("Not a MS Word file.");
}
return Arrays.stream(textExtractor.getText().split("\\s+"))
.filter(s -> s.matches("^.*[\\p{L}\\p{N}].*$"))
.count();
}
The regex at the bottom can be adjusted if needed, but overall this one has proved fairly resilient.
I have a block of jsp code like this. Here blockerdata, criticaldata, majordata and minordata are stringbuilder strings and their value is appended through a loop and value is assigned dynamically. Now I'm tryong to write them into an xml file like this.
<%
System.out.println(blockerdata);
System.out.println(criticaldata);
System.out.println(majordata);
System.out.println(minordata);
try
{
File file1 = new File("WebContent/criticaldata.xml");
File file2 = new File("WebContent/majordata.xml");
File file3 = new File("WebContent/minordata.xml");
File file4 = new File("WebContent/blockerdata.xml");
FileOutputStream fop1 = new FileOutputStream(file1);
FileOutputStream fop2 = new FileOutputStream(file2);
FileOutputStream fop3 = new FileOutputStream(file3);
FileOutputStream fop4 = new FileOutputStream(file4);
// if file doesnt exists, then create it
if (!file1.exists()) {
file1.createNewFile();
}
if (!file2.exists()) {
file2.createNewFile();
}
if (!file3.exists()) {
file3.createNewFile();
}
if (!file4.exists()) {
file4.createNewFile();
}
// get the content in bytes
byte[] contentInBytes1= criticaldata.toString().getBytes();
byte[] contentInBytes2= majordata.toString().getBytes();
byte[] contentInBytes3= minordata.toString().getBytes();
byte[] contentInBytes4= blockerdata.toString().getBytes();
fop1.write(contentInBytes1);
fop2.write(contentInBytes1);
fop3.write(contentInBytes1);
fop4.write(contentInBytes1);
fop1.flush();
fop2.flush();
fop3.flush();
fop4.flush();
fop1.close();
fop2.close();
fop3.close();
fop4.close();
}
catch ( IOException e)
{
}
%>
Problem is, the code doesn't seem to be working. I tried to do it using printwriter also but
the files are not being generated. Also I want to rewrite the file if it already exists. Can somebody please help me on how to do this ?
Good afternoon all,
Come to my case, I'm generating a docx document Junction 2 other docx, I'm doing a merge.
public static void main(String[] args) throws Exception {
InputStream in1 = new FileInputStream(new File("C:\\Clientes\\Constremac\\Repositorio_DOCS\\UPLOAD\\LAYOUT_PAGINA_VERSAO_FINAL.docx"));
InputStream in2 = new FileInputStream(new File("C:\\Clientes\\Constremac\\Repositorio_DOCS\\UPLOAD\\modeloContratoSocial.docx"));
OutputStream out = new FileOutputStream(new File("C:\\Clientes\\Constremac\\Repositorio_DOCS\\UPLOAD\\modeloContratoSocialMerge.docx"));
mergeDocx(in1,in2,out);
}
public static void mergeDocx(InputStream s1, InputStream s2, OutputStream os) throws Exception {
WordprocessingMLPackage target = WordprocessingMLPackage.load(s1);
insertDocx(target.getMainDocumentPart(), IOUtils.toByteArray(s2));
SaveToZipFile saver = new SaveToZipFile(target);
saver.save(os);
}
private static void insertDocx(MainDocumentPart main, byte[] bytes) throws Exception {
AlternativeFormatInputPart afiPart = new AlternativeFormatInputPart(new PartName("/part" + (chunk++) + ".docx"));
afiPart.setContentType(new ContentType(CONTENT_TYPE));
afiPart.setBinaryData(bytes);
Relationship altChunkRel = main.addTargetPart(afiPart);
//convertAltChunks()
CTAltChunk chunk = Context.getWmlObjectFactory().createCTAltChunk();
chunk.setId(altChunkRel.getId());
main.addObject(chunk);
}
My final document (docx) is ok, I can open it normally. The problem occurs when I will convert this generated file to PDF, the following error appears: NOT IMPLEMENTED: support for w: altChunk -.
public boolean createPDF(String nomeArquivo) {
try {
long start = System.currentTimeMillis();
Configuration confg = new Configuration();
System.out.println(Configuration.repositorioUpload + nomeArquivo + ".docx");
InputStream is = new FileInputStream(new File(Configuration.repositorioUpload + nomeArquivo + ".docx"));
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(is);
PdfSettings pdfSettings = new PdfSettings();
OutputStream out = new FileOutputStream(new File(Configuration.repositorioUpload + nomeArquivo + ".pdf"));
PdfConversion converter = new Conversion(wordMLPackage);
converter.output(out, pdfSettings);
System.err.println("Generate " + Configuration.repositorioUpload + nomeArquivo + ".pdf" + " with " + (
System.currentTimeMillis() - start) + "ms");
}
catch (Throwable e) {
e.printStackTrace();
}
return false;
}
I'm sending the java code i use, for a while I'm trying to generate this pdf, if anyone able to help me I am grateful.
Thank you all.
Hugs!
I found a way to use AltChunck, but even beyond not run correctly merge the images footer and header when exported to PDF does not appear.
public static void main(String[] args) throws Exception {
boolean ADD_TO_HEADER = true;
HeaderPart hp = null;
String inputfilepath = "C:\\Clientes\\Constremac\\Repositorio_DOCS\\UPLOAD\\default_template.xml";
String chunkPath = "C:\\Clientes\\Constremac\\Repositorio_DOCS\\UPLOAD\\sample.docx";
boolean save = true;
String outputfilepath = "C:\\Clientes\\Constremac\\Repositorio_DOCS\\UPLOAD\\altChunk_out.docx";
// Open a document from the file system
// 1. Load the Package
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new java.io.File(inputfilepath));
//proce
MainDocumentPart main = wordMLPackage.getMainDocumentPart();
if (ADD_TO_HEADER) {
hp = wordMLPackage.getDocumentModel().getSections().get(0).getHeaderFooterPolicy().getDefaultHeader();
}
AlternativeFormatInputPart afiPart = new AlternativeFormatInputPart(new PartName("/chunk.docx"));
afiPart.setBinaryData(new FileInputStream(chunkPath));
afiPart.setContentType(new ContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml")); //docx
//afiPart.setContentType(new ContentType("application/xhtml+xml")); //xhtml
Relationship altChunkRel = null;
if (ADD_TO_HEADER) {
altChunkRel = hp.addTargetPart(afiPart);
} else {
altChunkRel = main.addTargetPart(afiPart);
}
CTAltChunk ac = Context.getWmlObjectFactory().createCTAltChunk();
ac.setId(altChunkRel.getId());
if (ADD_TO_HEADER) {
hp.getJaxbElement().getEGBlockLevelElts().add(ac);
} else {
main.addObject(ac);
}
// Save it
if (save) {
SaveToZipFile saver = new SaveToZipFile(wordMLPackage);
saver.save(outputfilepath);
System.out.println("Saved " + outputfilepath);
}
}
What am I doing wrong?
An altChunk is not "real" docx content.
Before it can be outputted in PDF, it needs to be replaced with normal WordML paragraphs, tables etc.
You can try doing this yourself, which is easy enough if the content does not include any relationships (images, hyperlinks etc), or conflicting styles or numbering. Please see further http://www.docx4java.org/blog/2010/11/merging-word-documents/ .. or my company's website plutext.com
This can be solved
An altChunk is not "real" docx content.
using java we can convert altchunk to original content word tags,
convert the document.xml inside docx
Docx4jProperties.setProperty(“docx4j.Convert.Out.HTML.OutputMethodXML”,
true);
Docx4J.toHTML(htmlSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);
Open the link for complete code.
[Convert AltChunk To Original Content][1]
https://kishankichi.wordpress.com/2016/05/26/convert-altchunk-to-original-content-or-convert-to-real-docx-format-using-java
https://kishankichi.wordpress.com/2016/05/26/convert-altchunk-to-original-content-or-convert-to-real-docx-format-using-java/
Note:
Kindly ignore   and other such tags in your html content.
I have checked only for  .
Thanks for the replay...
I have a filename in my code as :
String NAME_OF_FILE="//sdcard//imageq.png";
FileInputStream fis =this.openFileInput(NAME_OF_FILE); // 2nd line
I get an error on 2nd line :
05-11 16:49:06.355: ERROR/AndroidRuntime(4570): Caused by: java.lang.IllegalArgumentException: File //sdcard//imageq.png contains a path separator
I tried this format also:
String NAME_OF_FILE="/sdcard/imageq.png";
The solution is:
FileInputStream fis = new FileInputStream (new File(NAME_OF_FILE)); // 2nd line
The openFileInput method doesn't accept path separators.
Don't forget to
fis.close();
at the end.
This method opens a file in the private data area of the application. You cannot open any files in subdirectories in this area or from entirely other areas using this method. So use the constructor of the FileInputStream directly to pass the path with a directory in it.
openFileInput() doesn't accept paths, only a file name
if you want to access a path, use File file = new File(path) and corresponding FileInputStream
I got the above error message while trying to access a file from Internal Storage using openFileInput("/Dir/data.txt") method with subdirectory Dir.
You cannot access sub-directories using the above method.
Try something like:
FileInputStream fIS = new FileInputStream (new File("/Dir/data.txt"));
You cannot use path with directory separators directly, but you will
have to make a file object for every directory.
NOTE: This code makes directories, yours may not need that...
File file= context.getFilesDir();
file.mkdir();
String[] array=filePath.split("/");
for(int t=0; t< array.length -1 ;t++)
{
file=new File(file,array[t]);
file.mkdir();
}
File f=new File(file,array[array.length-1]);
RandomAccessFileOutputStream rvalue = new RandomAccessFileOutputStream(f,append);
String all = "";
try {
BufferedReader br = new BufferedReader(new FileReader(filePath));
String strLine;
while ((strLine = br.readLine()) != null){
all = all + strLine;
}
} catch (IOException e) {
Log.e("notes_err", e.getLocalizedMessage());
}
File file = context.getFilesDir();
file.mkdir();
String[] array = filePath.split("/");
for(int t = 0; t < array.length - 1; t++) {
file = new File(file, array[t]);
file.mkdir();
}
File f = new File(file,array[array.length- 1]);
RandomAccessFileOutputStream rvalue =
new RandomAccessFileOutputStream(f, append);
I solved this type of error by making a directory in the onCreate event, then accessing the directory by creating a new file object in a method that needs to do something such as save or retrieve a file in that directory, hope this helps!
public class MyClass {
private String state;
public File myFilename;
#Override
protected void onCreate(Bundle savedInstanceState) {//create your directory the user will be able to find
super.onCreate(savedInstanceState);
if (Environment.MEDIA_MOUNTED.equals(state)) {
myFilename = new File(Environment.getExternalStorageDirectory().toString() + "/My Directory");
if (!myFilename.exists()) {
myFilename.mkdirs();
}
}
}
public void myMethod {
File fileTo = new File(myFilename.toString() + "/myPic.png");
// use fileTo object to save your file in your new directory that was created in the onCreate method
}
}
I did like this
var dir = File(app.filesDir, directoryName)
if(!dir.exists()){
currentCompanyFolder.mkdir()
}
var directory = app.getDir(directoryName, Context.MODE_PRIVATE)
val file = File(directory, fileName)
file.outputStream().use {
it.write(body.bytes())
}