I wrote a program that creates a set of data that is outputted to an excel spreadsheet. I was originally using the jexcel library to write the data to the file, but I'd like to update the program so that it can check and see whether is should create a ".xls" or ".xlsx" file, then write to the appropriate document type. Apache POI seems to be the best option in terms of writing to a ".xlsx" file, but any ideas about determining the correct file type?
I could just have the user choose when naming the file, but that seems like extra work for the user and I'm assuming that there are users who don't know what file type they'd want.
Any ideas?
Also, I'm assuming the OS is windows and the user has some version of excel, in other cases I'll just choose a default file type.
One way is to call the Windows ASSOC and FTYPE commands, capture the output and parse it to determine the Office version installed.
C:\Users\me>assoc .xls
.xls=Excel.Sheet.8
C:\Users\me>ftype Excel.sheet.8
Excel.sheet.8="C:\Program Files (x86)\Microsoft Office\Office12\EXCEL.EXE" /e
Here a quick example :
import java.io.*;
public class ShowOfficeInstalled {
public static void main(String argv[]) {
try {
Process p = Runtime.getRuntime().exec
(new String [] { "cmd.exe", "/c", "assoc", ".xls"});
BufferedReader input =
new BufferedReader
(new InputStreamReader(p.getInputStream()));
String extensionType = input.readLine();
input.close();
// extract type
if (extensionType == null) {
System.out.println("no office installed ?");
System.exit(1);
}
String fileType[] = extensionType.split("=");
p = Runtime.getRuntime().exec
(new String [] { "cmd.exe", "/c", "ftype", fileType[1]});
input =
new BufferedReader
(new InputStreamReader(p.getInputStream()));
String fileAssociation = input.readLine();
// extract path
String officePath = fileAssociation.split("=")[1];
System.out.println(officePath);
}
catch (Exception err) {
err.printStackTrace();
}
}
}
You may want to add more error checking and the parsing to extract the Office version from the returned path is left as an exercise ;-)
You can search in the registry for the key:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths
This will probably require some work, as evidenced by this question:
read/write to Windows Registry using Java
If you're willing to dive into the registry (eg with jregistrykey) a translated version of this PowerShell script should do what you want.
Take a look at OfficeVer.
You can implement it to your script or use it for code analysis. It's cross-platform much like Java, so compiling it and implementing it directly shouldn't be a big deal.
It works by extracting .docx and xlsx files and then reading the version, as well as reading directly from .doc and .xls files.
OfficeVer as well has extended their support to .pdf files (current version as of time of writing is 1.03.1)
Related
I'm trying to unpack/extract an archive, which is supplied in my program, containing binaries.
The copy from within the jar to the file works just fine, but when I try to extract the zip, it returns unexpectedly and only copies half of a file, and ignores the other file completely.
Here's a bit more detailed description:
I'm trying to unzip an archive copied to a folder, from within the program's .jar.
The program I'm using to unzip is "unzip" (comes with Linux).
The command used to extract is:
unzip -o <file>.zip
which is exactly what I'm using in following code:
ProcessBuilder process = new ProcessBuilder();
process.command("unzip", "-o", adb_tools.toString());
process.redirectErrorStream(true);
Process pr = process.start();
String line;
BufferedReader processReader = new BufferedReader(new InputStreamReader(pr.getInputStream()));
while ((line = processReader.readLine()) != null)
log(Level.INFO, "Extracting Android Debugging Bridge: " + line, true);
log(Level.INFO, "Android Debugging Bridge has been extracted and installed to system. Marking files as executable...", true);
pr.destroy();
processReader.close();
When I use the command directly via the Terminal, everything works fine, both files are extracted and inflated, and are executable, however, as mentioned above, when I use the command in Java, only one file gets copied (and even that only goes half way), and the other file is completely ignored.
How can I fix this problem, and prevent this happening again, with different programs?
Thanks in advance!
If you need to do a common task in Java, there is always a library out there which does what you need better than yourself. So use an external library for unzipping. Check here:
What is a good Java library to zip/unzip files?
It looks like you can use zip4j like this (from djangofan's answer):
public static void unzip(){
String source = "some/compressed/file.zip";
String destination = "some/destination/folder";
String password = "password";
try {
ZipFile zipFile = new ZipFile(source);
if (zipFile.isEncrypted()) {
zipFile.setPassword(password);
}
zipFile.extractAll(destination);
} catch (ZipException e) {
e.printStackTrace();
}
}
Is there any possible way to retrieve information of my graphic card adapter using Java API?
I know that DirectX can easily do it, however, I just wonder if Java can do this...?
Like picture below.. DirectX finds out GPU adapter integrated to my hardware, and a list of its supporting resolutions.
My problem is, is there an API that Java would do this kind of thing?
I really wonder if Java is able to get information regarding to Video Card.
Thank you.
As #Sergey K. said in his answer there are several ways to do this. One of these is using dxdiag tool (obviously it will only work on Windows) particularly dxdiag /t variant that will redirect the output to a given file. Then you can process that file to get required info:
public static void main(String[] args) {
try {
String filePath = "./foo.txt";
// Use "dxdiag /t" variant to redirect output to a given file
ProcessBuilder pb = new ProcessBuilder("cmd.exe","/c","dxdiag","/t",filePath);
System.out.println("-- Executing dxdiag command --");
Process p = pb.start();
p.waitFor();
BufferedReader br = new BufferedReader(new FileReader(filePath));
String line;
System.out.println(String.format("-- Printing %1$1s info --",filePath));
while((line = br.readLine()) != null){
if(line.trim().startsWith("Card name:") || line.trim().startsWith("Current Mode:")){
System.out.println(line.trim());
}
}
} catch (IOException | InterruptedException ex) {
ex.printStackTrace();
}
}
Generated file will look like this:
And output will look like this:
-- Executing dxdiag command --
-- Printing ./foo.txt info --
Card name: Intel(R) HD Graphics Family
Current Mode: 1366 x 768 (32 bit) (60Hz)
There are several ways you can do this in Java. But all of them end up using DirectX/OpenGL/C++/WinAPI/whatever as their back-end.
You will need Java bindings for either of this API. Or you can write your code in C/C++ and use it via JNI.
I'm trying to convert files from png's to pdf using imagemagick and Java. I've got everything working to a place when I'm executing imagemagick command to actually merge multiple png's into one pdf. The command itself looks properly, and it works fine when executed in the terminal but my application gives me error showing that imgck can't open the file (even though it exists and I've set permissions to the folder to 777 :
line: convert: unable to open image `"/Users/mk/Documents/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/sch-java/print-1357784001005.png"': No such file or directory # error/blob.c/OpenBlob/2642.
This is my command :
/opt/local/bin/convert "/Users/mk/Documents/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/sch-java/print-1357784001005.png" "/Users/mk/Documents/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/sch-java/print-1357784001219.png" "/Users/mk/Documents/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/sch-java/complete-exportedPanel2013-01-1003:13:17.212.pdf"
And my Java code :
String filesString = "";
for (String s : pdfs){
filesString += "\""+ s + "\" ";
}
Process imgkProcess = null;
BufferedReader br = null;
File f1 = new File(pdfs[0]);
//returns true
System.out.println("OE: "+f1.exists());
String cmd = imgkPath+"convert "+ filesString+ " \""+outputPath+outName+"\"";
try {
imgkProcess = Runtime.getRuntime().exec(cmd);
InputStream stderr = imgkProcess.getErrorStream();
InputStreamReader isr = new InputStreamReader(stderr);
br = new BufferedReader(isr);
} catch (IOException e1) {
msg = e1.getMessage();
}
imgkProcess.waitFor();
while( (line=br.readLine() ) != null){
System.out.println("line: "+line);
}
The whole code is executed from a java servlet controller after getting request from a form. Any ideas what can cause this ? I'm using latest imgck, jdk, and osx 10.7 .
A few things:
When spawning anything but really trivial processes, it's usually better to use ProcessBuilder than Runtime.exec() - it gives you much better control
Even with ProcessBuilder, it often works better to write a shell script that does what you need. Then spawn a process to run the script. You get a lot more control in shell script than you do in ProcessBuilder
Remember that a spawned process is not a shell. It can't, for instance, evaluate expressions, or expand shell variables. If you need that, then you must execute a shell (like sh or bash). Better yet, write a shell script as described above
If all you need to do is to execute some ImageMagick commands, it would probably be easier to jmagick, a Java interface to ImageMagick - see http://www.jmagick.org/
Actually, since the you're assembling images into a PDF, the iText library - http://itextpdf.com is probably the best tool for the job, as it is native Java code, does not require spawning a native process, and will therefore be much more portable.
Solved it by adding all arguments to an arrayList and then casting it to String array.
ArrayList<String> cmd = new ArrayList<String>();
cmd.add(imgkPath+"convert");
for (int i=0, l=pdfs.length; i<l; i++){
cmd.add(pdfs[i]);
}
cmd.add(outputPath+outName);
imgkProcess = Runtime.getRuntime().exec(cmd.toArray(new String[cmd.size()]));
I am making a project for college and have made a program which creates csv files. I would like there to be a button which you can click which then opens the csv file with excel. Thanks
Knowing that MsOffice is installed on the system, you should be able to open a document with it from command line using the command
excel myDoc.csv
to execute such a command from java, you could use this snapshot:
File myCSVFile; //reference to your file here
String execString = "excel " + myCSVFile.getAbsolutePath();
Runtime run = Runtime.getRuntime();
try {
Process pp = run.exec(execString);
} catch(Exception e) {
e.printStackTrace();
}
This is somewhat rough and needs styling, of course, but generally it should work. Besides, to be more graceful you could also check Windows registry, using the java.util.prefs.Preferences class, to know if MsOffice is installed and, if yes, where. But, please, be aware, if you are reckoning for MsExcel (as I understood from your post), this will automatically cancel Java's multiplatform approach. Hopefully, this helps :)
If you are using Java 6 you can use the Desktop class. Read also Opening, Editing, and Printing a File
You can use JExcel API. It will be very easy for you.
For whatever reason, execString's provided did not work for me, but the one below worked:
String execString = "cmd /c start excel \"" + filePathString + "\"";
With the other exeString's I kept getting an exception saying that the runtime cannot find the file - start or excel.
I need to find out default file opener for a given file on Windows so that I can customize the command arguments and open the file with the default opener/viewer.
My real usage scenario is opening multiple multimedia files with user's default media player so that all the files will be added to user's playlist (For the players that can open multiple files on the same intance). For operating system other than Windows I use Desktop.open(File file) method (I simply does not concern opening multiple files feature for OSs other than Windows), I cannot find any method which I can open multiple files other than customizing command arguments and running it using exec() method of the Runtime class. I use somethig similar to this:
private void playItems2(List<File> fileList, String playerBinary) {
String args = " ";
for (File file : fileList) {
args += "\"" + file.getAbsolutePath() + "\" ";
}
try {
String command = playerBinary + args;
Runtime rt = Runtime.getRuntime();
Process p = rt.exec(command);
} catch (Exception exc) {/*handle exception*/
System.err.println("Run Player Exc:" + exc.getMessage());
}
}
I am using user specified path for the playerBinary, what I need to is automatically detecting default player for the first item of fileList and use it as playerBinary.
I have also looked at Rundll32.exe and cmd.exe /start solutions but they did not work for my usage scenario.
This question should not be confused with this and this.
Use this approach to call default opener and enjoy!
public void playItems2(...) throws Exception {
...
Process p = Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler c:/mp3/myfile.mp3");
p.waitFor();
...
}
Cannot do with pure Java alone.
In case of Windows, you need to read registry. Suppose you need to find out file association for .mp3
In the windows registry, look the default value for
HKEY_CLASSES_ROOT\.mp3. Usually its
"mp3file".
Now look for
HKEY_CLASSES_ROOT\mp3file\shell\open\command.
The value in there is a string
pointing to an executable to open
.mp3 files with.
Now this cant be done in Java, you need to choose appropriate 3rd party lib to do this for you.