2015-11-26 56 views
6

我想創建一個簡單的PDF文檔使用Android本機PdfDocument類(從API 19)。我想要的是有一個XML佈局文件,例如pdf_doc.xml,然後在創建PDF時對其進行充氣。在pdf_doc.xml裏面,我會看到一堆可以在代碼中獲取的視圖,然後單獨繪製到PdfDocuments頁面上。問題是,這會創建一個損壞的PDF文件。另一方面,如果我只是在我的main_activity.xml(我在創建PDF時使用的活動的xml)中創建一個簡單的TextView,並使用該TextView,它可以正常工作。Android PdfDocument損壞時,保存到外部存儲

爲什麼TextView來自膨脹的佈局或活動的佈局有什麼區別?我是否試圖以錯誤的方式做到這一點?

僅供參考:以編程方式創建TextView時也失敗。

以下是我的源代碼。這兩個功能在彼此之後立即被調用。第一個創建PDF,另一個保存。問題是在我看來,被稱爲內容,即時通訊膨脹的佈局。如果我將該TextView放在Activity的XML中,然後從活動中獲取它,就像act.findViewById(R.id.pdf_text);一樣,然後按預期工作。

代碼:

public static PdfDocument createPdf(Activity act){ 
     PrintAttributes printAttrs = new PrintAttributes.Builder(). 
       setColorMode(PrintAttributes.COLOR_MODE_COLOR). 
       setMediaSize(PrintAttributes.MediaSize.ISO_A4). 
       setMinMargins(PrintAttributes.Margins.NO_MARGINS). 
       build(); 

     ViewGroup mainLayout = (ViewGroup) View.inflate(act, R.layout.pdf_doc, null); 

     int pageHeight = printAttrs.getMediaSize().getHeightMils()/1000 * 72; 
     int pageWidth = printAttrs.getMediaSize().getWidthMils()/1000 * 72; 

     PdfDocument document = new PrintedPdfDocument(act, printAttrs); 
     PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(pageWidth, pageHeight, 1).create(); 
     PdfDocument.Page page = document.startPage(pageInfo); 

     View content = mainLayout.findViewById(R.id.pdf_text); 
     content.draw(page.getCanvas()); 
     document.finishPage(page); 

     return document; 
    } 

    public static void saveFile(PdfDocument doc){ 
     String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString(); 
     File myDir = new File(root + "/pdf_test"); 
     myDir.mkdirs(); 

     File file = new File(myDir, "test.pdf"); 

     if (file.exists()) { 
      file.delete(); 
     } 

     try { 
      FileOutputStream out = new FileOutputStream(file); 
      doc.writeTo(out); 
      doc.close(); 
      out.flush(); 
      out.close(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     String path = file.getAbsolutePath(); 
     Log.d("pdftest", "path: " + path); 
    } 
+0

@ FrankN.Stein也許我還不夠清楚,但我不打算一下子畫出整個佈局。我只是從佈局中取出一個TextView並試圖繪製它。我看不出這樣做的區別,相比之下,從活動使用的佈局來看...... –

+0

根本沒有。正如我所說,如果我從活動的XML中取出一個TextView,我可以將它繪製到PdfDocument頁面畫布上,但是我無法使用編程式膨脹佈局中的TextView執行此操作? –

回答

1

兩個建議:

  1. 由於您mainLayout將具有零高度和寬度爲零(你有沒有誇大其到父),嘗試手動鋪設了,依次呼叫measure()layout()。您將需要指定想要佈局大小的像素大小。

  2. out.flush()之後和out.close()之前致電out.getFd().sync()。我懷疑這是造成你的具體問題,但這是一個好主意,不太可能受到傷害。

+0

謝謝你提出了兩個建設性的建議。我明天早上會試試看! –

+0

如果我希望佈局只填充儘可能多的空間,那麼measure()的參數是什麼?最多? –

+0

@ThomasTeilmann:打我。我沒有嘗試過。我不確定是否有「儘可能多的空間」,因爲沒有父母。由於IIRC必須以像素爲單位提供紙張大小,因此可能會使用相同數量的像素(或可能少一些)。 – CommonsWare