【问题标题】:How to render PDF in Android如何在 Android 中渲染 PDF
【发布时间】:2011-02-22 10:11:58
【问题描述】:

在我的应用程序中,我将收到一个字节流并将其转换为手机内存中的 pdf 文件。如何将其呈现为 pdf?并在活动中展示它?

【问题讨论】:

标签: java android pdf


【解决方案1】:

某些手机(例如 Nexus One)预装了 Quickoffice 版本,因此只要将文件保存到 SD 卡,就可以像发送相应的 Intent 一样简单。

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();
                    }
                }
            }
        });
    }
}

【讨论】:

  • 嗯明天试试这个。所以从字节流中我会得到我需要将它们保存为文件,然后尝试执行该代码。
  • 嗯,如果我的 Android 系统中没有安装 QuickOffice 怎么办?
  • 所以?如果您没有 QuickOffice 怎么办?
  • 如果手机没有快捷办公那么?
  • 如何直接从服务器打开PDF文件?而不是将其保存在设备上然后打开。
【解决方案2】:

Open pdf file in 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);
  }
}

【讨论】:

  • 我认为这只适用于谷歌查看器链接,因为它只提供图像。如果我们直接使用 pdf 的链接,它将不起作用。对吗?
  • 这似乎不适用于本地文件,仅适用于远程文件。
  • 如果链接发生变化怎么办?
  • "在持续测试了 2 天后,我在 Google 文档上收到错误消息,说您已达到查看或下载非 Google 文档格式文件的带宽限制.....所以看起来不太可靠。” stackoverflow.com/questions/2655972/…
【解决方案3】:

Android-Lollipop (api 21) 引入了一个新的 API:PdfRenderer

此 API 允许您从 PDF 文档中的页面创建位图。

很快:

  • 从您的 pdf 文档中获取可查找的文件描述符:

      ParcelFileDescriptor fd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
    
  • 创建 PdfRenderer

      PdfRenderer renderer = new PdfRenderer(fd);
    
  • 准备位图

      Bitmap bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_4444);
    
  • 获取PdfRenderer.Page 进行渲染

      PdfRenderer.Page page = renderer.openPage(pageIndex);
    
  • 在准备好的位图上渲染页面

      page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
    
  • 现在你可以用位图做你想做的事了。

  • 请注意,2 个空参数可能允许您剪辑页面中的某些部分并执行剪辑的转换(使用 Matrix

  • 还有另一种渲染模式:RENDER_MODE_FOR_PRINT。如果您需要这种模式,有一些指南可以正确使用它:这里是the details

【讨论】:

  • 有什么方法可以在不保存手机文件的情况下实现这一点?我将 PDF 作为字节流获取,我需要将其显示给用户而不将其保存在手机上。
  • 约束是将可查找的文件描述符传递给构造函数;并且来自套接字流的 fd 是不可搜索的。您可以尝试将流中的所有字节存储在缓冲区中并从中获取可搜索的 fd。
【解决方案4】:

这个库很简单并且运行良好: Android Pdf Viewer https://github.com/barteksc/AndroidPdfViewer

旧回复...

我认为 Joan Zapata 给了我们更好更简单的解决方案:

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

我向你保证它有效!

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

【讨论】:

  • Alecs:pdfView.fromAsset(pdfName) 中的 pdfName 是用什么做的?我尝试使用绝对路径,但找不到该文件(我确定它在那里)。示例:/data/data/package.name/files/images/filename.pdf
  • 亲爱的@h-bomb,当您的 pdf 位于项目的资产目录中时,您必须使用 fromasset 方法。要从设备加载 pdf,您可以使用 fromFile 方法。
  • 非常感谢。我决定使用 Android 的 FileProvider 并允许外部应用程序打开 PDF。令人惊讶的是,FileProvider 开发文档中的文档和示例代码非常出色。
【解决方案5】:

对于本地的pdf文件,可以通过第三方库进行渲染。例如,使用MuPDF library,其支持的文件类型包括PDF、PNG和JPEG。

MuPDF 的一个缺点是它使用原生库来实现目标,因此以后将应用程序移植到黑莓平台上并不容易。

【讨论】:

    【解决方案6】:

    要从字节数组打开 pdf,您可以使用RadaeePDF,您可以在活动中执行以下操作:

    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 );
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-28
      • 2011-10-28
      • 1970-01-01
      • 1970-01-01
      • 2016-09-24
      • 1970-01-01
      • 2013-07-05
      相关资源
      最近更新 更多