public class PDFSplitor {
public PDFSplitor(){
}
/**
* Set PDF file name to special to split
* @param fileName PDF file name
* @exception java.io.IOException if an I/O error occurs
*/
public void setFile(String fileName) throws IOException{
pdfFile = new File(fileName);
if( !pdfFile.exists() || !pdfFile.isFile() ){
pdfFile = null;
throw new IOException(fileName + "not find!");
}
else{
reader = new PdfReader(fileName);
document = new Document(reader.getPageSizeWithRotation(1));
pageNumber = reader.getNumberOfPages();
//writer = PdfWriter.getInstance(document,)
}
}
/**
* Get the bytes of next page
* @return the bytes of next page .If file reachs end , return null.
* @throws IOException
* @throws IOException if PDF document error occurs
*/
public byte[] nextPage() throws IOException {
try{
if( ++pageCounter <= pageNumber ){
ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
writer = PdfWriter.getInstance(document, byteOutStream);
if (shouldEntrypted) {
writer.setEncryption(is128bit, usrPassword, ownerPassword, 0);
}
document.open();
PdfContentByte content = writer.getDirectContent();
PdfImportedPage page = writer.getImportedPage(reader, pageCounter);
int rotation = reader.getPageRotation(pageCounter);
if (rotation == 90 || rotation == 270) {
content.addTemplate(page, 0, -1f, 1f, 0, 0, reader.getPageSizeWithRotation(pageCounter).height());
}
else {
content.addTemplate(page, 1f, 0, 0, 1f, 0, 0);
}
document.close();
writer.close();
reader.removeUnusedObjects();
reader.eliminateSharedStreams();
return byteOutStream.toByteArray
();
}
else{
return null;
}
}catch(DocumentException e){
throw new IOException(e.toString());
}
}
/**
* Finish one task of splitting and can call setFile(String fileName) to begin another task.
*/
public void close(){
pageNumber = 0;
pageCounter = 0;
pdfFile = null;
reader = null;
shouldEntrypted = false;
}
public void skip(int pageNum){
pageCounter += pageNum;
}
public int getPageNumber(){
return pageNumber;
}
/**
* Tell Splitor to entrypt output pages.
* @param usrPassword PDF contents' user-password ,can be null (This password will be required before the file's openning)
* @param ownerPassword PDF contents' owner-password, can be null (This password will be required before the file's changing)
* @param is128bit true for 128 bit key length. false for 40 bit key length
*/
public void setEncryption(String usrPassword, String ownerPassword, boolean is128bit){
this.ownerPassword = ownerPassword;
this.usrPassword = usrPassword;
this.is128bit = is128bit;
shouldEntrypted = true;
}
/**For debug: pass a PDF-file name then it will spit the file*/
public static void main(String[] args) {
try {
String fileName = args[0];
PDFSplitor splitor = new PDFSplitor();
splitor.setFile(fileName);
splitor.setEncryption(null, null, true);
byte[] buffer;
int num = 0;
int page = 0;
while ( ( buffer=splitor.nextPage()) != null){
int dotIndex =
fileName.indexOf('.');
if(dotIndex>=0){
fileName = fileName.substring(0,dotIndex);
}
FileOutputStream out = new FileOutputStream(fileName+"_"+ ++num + ".pdf");
out.write(buffer);
out.close();
System.gc();
System.gc();
System.out.println("finished page:" + (page++));
}
splitor.close();
}
catch(Exception e){
e.printStackTrace();
}
}
private File pdfFile;
private PdfReader reader;
private int pageCounter = 0;
private int pageNumber = 0;
private Document document;
private PdfWriter writer;
private String usrPassword;
private String ownerPassword;
private boolean is128bit;
private boolean shouldEntrypted;
}