Cách kết xuất PDF trong Android


81

Trong ứng dụng của tôi, tôi sẽ nhận một luồng byte và chuyển nó thành tệp pdf trong bộ nhớ điện thoại. Làm cách nào để kết xuất nó thành pdf? Và hiển thị nó trên một hoạt động?


Điều này đã được trả lời ở đây: stackoverflow.com/a/16294833/2027232
Nicolas Tyler

Câu trả lời:


115

Một số điện thoại (như Nexus One) được cài đặt sẵn phiên bản Quickoffice nên việc gửi Ý định phù hợp có thể dễ dàng như gửi Ý định thích hợp sau khi bạn đã lưu tệp vào thẻ SD.

public class OpenPdf extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button button = (Button) findViewById(R.id.OpenPdfButton);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                File file = new File("/sdcard/example.pdf");

                if (file.exists()) {
                    Uri path = Uri.fromFile(file);
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setDataAndType(path, "application/pdf");
                    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

                    try {
                        startActivity(intent);
                    } 
                    catch (ActivityNotFoundException e) {
                        Toast.makeText(OpenPdf.this, 
                            "No Application Available to View PDF", 
                            Toast.LENGTH_SHORT).show();
                    }
                }
            }
        });
    }
}

1
hmm tôi hãy thử cái này vào ngày mai. vì vậy từ các luồng byte, tôi sẽ nhận được tôi cần phải lưu chúng dưới dạng tệp và sau đó thử thực hiện mã đó.
Mikey

18
hmm thì sao nếu tôi chưa cài đặt QuickOffice trong Android của mình?
Mikey

2
vì thế? điều gì xảy ra nếu bạn không có QuickOffice?
Necronet

Nếu điện thoại không có Office nhanh thì?
Tofeeq Ahmad

6
Làm cách nào để mở tệp PDF trực tiếp từ Máy chủ? Thay vì lưu nó trên thiết bị và sau đó mở.
EnthuDeveloper

16

Mở tệp pdf trong webview .

public class MyPdfViewActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    WebView mWebView=new WebView(MyPdfViewActivity.this);
    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.getSettings().setPluginsEnabled(true);
    mWebView.loadUrl("https://docs.google.com/gview?embedded=true&url="+LinkTo);
    setContentView(mWebView);
  }
}

tôi nghĩ điều này chỉ hoạt động với liên kết người xem google, vì nó chỉ phục vụ hình ảnh. Nếu chúng ta sử dụng liên kết tới pdf trực tiếp, nó sẽ không hoạt động. Đúng không ?
Nathan Do

Điều này dường như không hoạt động đối với các tệp cục bộ, chỉ những tệp từ xa.
Alfie Hanssen

2
Nếu liên kết sẽ thay đổi thì sao?
Shuhrat Akramov,

3
"Sau khi kiểm tra liên tục trong 2 ngày, tôi gặp lỗi trên Google docs cho biết Bạn đã đạt đến giới hạn băng thông để xem hoặc tải xuống các tệp không ở định dạng Google Documents ..... Vì vậy, có vẻ như không đáng tin cậy." stackoverflow.com/questions/2655972/…
Wédney Yuri,

9

Android-Lollipop (api 21) giới thiệu một API mới: PdfRenderer

API này cho phép bạn tạo Bitmap từ một trang trong tài liệu PDF.

Ngắn gọn:

  • lấy bộ mô tả tệp có thể tìm kiếm từ tài liệu pdf của bạn:

      ParcelFileDescriptor fd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
    
  • tạo PdfRenderer

      PdfRenderer renderer = new PdfRenderer(fd);
    
  • chuẩn bị Bitmap

      Bitmap bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_4444);
    
  • lấy trang PdfRenderer.P để kết xuất

      PdfRenderer.Page page = renderer.openPage(pageIndex);
    
  • hiển thị trang trên bitmap đã chuẩn bị

      page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
    
  • bây giờ bạn có thể làm những gì bạn muốn với bitmap.

  • lưu ý rằng 2 args rỗng có thể cho phép bạn cắt một số phần trong trang và thực hiện chuyển đổi (sử dụng Ma trận ) của clip

  • có một chế độ kết xuất khác: RENDER_MODE_FOR_PRINT . Nếu bạn cần chế độ này, có một số hướng dẫn để sử dụng nó đúng cách: đây là chi tiết .


3
Có cách nào để đạt được điều này mà không cần lưu tệp trên điện thoại không? Tôi đang nhận PDF dưới dạng bytestream và tôi cần hiển thị nó cho người dùng mà không cần lưu trên điện thoại.
Gokhan Arik

ràng buộc là chuyển một bộ mô tả tệp có thể tìm kiếm cho hàm tạo; và fd từ luồng ổ cắm không thể tìm kiếm được. Bạn có thể cố gắng lưu trữ tất cả các byte từ luồng trong bộ đệm và nhận fd có thể tìm kiếm từ đó.
ben75

5

Thư viện này đơn giản và hoạt động tốt: Android Pdf Viewer https://github.com/barteksc/AndroidPdfViewer

Trả lời cũ ...

Tôi nghĩ rằng Joan Zapata cung cấp cho chúng tôi giải pháp tốt hơn và đơn giản:

https://github.com/JoanZapata/android-pdfview

Tôi đảm bảo với bạn rằng nó hoạt động!

1 : https://github.com/JoanZapata/android-pdfview


1
Alecs: Bạn đã sử dụng pdfName bằng pdfView.fromAsset(pdfName)gì? Tôi đã thử sử dụng đường dẫn tuyệt đối, nhưng không tìm thấy tệp (và tôi chắc chắn rằng nó ở đó). Ví dụ: /data/data/package.name/files/images/filename.pdf
h-bomb

1
@ H-bomb thân mến, bạn phải sử dụng phương pháp fromasset khi pdf của bạn nằm trong phần tài sản của dự án. Để tải pdf từ thiết bị, bạn có thể sử dụng phương thức fromFile .
Alecs

1
Cám ơn rất nhiều. Tôi quyết định sử dụng FileProvider của Android và cho phép một ứng dụng bên ngoài mở tệp PDF. Đáng ngạc nhiên là tài liệu và mã mẫu trong tài liệu dành cho nhà phát triển FileProvider rất tuyệt vời.
h-bomb

3

Đối với các tệp pdf cục bộ, bạn có thể hiển thị chúng thông qua các thư viện của bên thứ ba. ví dụ: sử dụng thư viện MuPDF , các loại tệp được hỗ trợ của nó bao gồm PDF, PNG và JPEG.

Một điểm thiếu sót của MuPDF là nó sử dụng thư viện gốc để thực hiện mục tiêu, vì vậy sẽ không dễ dàng để chuyển ứng dụng trên nền tảng BlackBerry sau này.


0

Để mở một pdf từ một mảng byte, bạn có thể sử dụng RadaeePDF, bạn có thể thực hiện như sau trong hoạt động của mình:

private PDFReader m_vPDF = null;
private Document doc = new Document();

public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    Global.Init(this);

    m_vPDF = new PDFReader(this);
    doc.Close();

    int ret = m_doc.OpenMem(data, password);
        switch( ret )
        {
            case -1://need input password
                finish();
                break;
            case -2://unknown encryption
                finish();
                break;
            case -3://damaged or invalid format
                finish();
                break;
            case -10://access denied or invalid file path
                finish();
                break;
            case 0://succeeded, and continue
                break;
            default://unknown error
                finish();
                break;
        }

    m_vPDF.open(doc);

    setContentView( m_vPDF );
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.