【问题标题】:Create PDF from RecyclerView full content?从 RecyclerView 完整内容创建 PDF?
【发布时间】:2017-07-27 05:50:04
【问题描述】:

问题已在此处提出:create PDF of RecyclerView in FULL length 而且我也有同样的问题,因为我还没有找到解决方案,我想生成完整长度的 RecyclerView 内容的 PDF。 但没有找到解决方案。

我已经尝试了所有可用的解决方案以及从 RecycleView 生成 PDF 的所有可能方法。

我已经尝试过的解决方案:

https://gist.github.com/PrashamTrivedi/809d2541776c8c141d9a

Take a screenshot of RecyclerView in FULL length

Convert Listview Items into a single Bitmap Image

已经尝试了上面提到的所有解决方案,但其中任何一个都不能与我一起工作并出现错误,有时宽度和高度问题或有时得到空白的白色位图作为输出不知道为什么。

问题:

我有带有 HTML 内容的 RecyclerView 以及内容之间的图像。

将跟随屏幕视为带有内容的 RecyclerView。

RecyclerView 中的内容与上图相同,包含 100 多个项目。

RecyclerView 项目布局:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fresco="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/leftImage"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_weight="1"
    android:adjustViewBounds="true"
    android:maxHeight="350dp"
    fresco:actualImageScaleType="fitCenter"
    fresco:placeholderImage="@color/white" />

<jp.wasabeef.richeditor.RichEditor
    android:id="@+id/editor"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="@dimen/margin10dp"
    android:layout_marginRight="@dimen/margin10dp"
    android:layout_weight="1"
    android:clickable="false"
    android:focusable="false"
    android:focusableInTouchMode="false" />

<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/rightImage"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_weight="1"
    android:adjustViewBounds="true"
    android:maxHeight="350dp"
    fresco:actualImageScaleType="fitCenter"
    fresco:placeholderImage="@color/white" />
</LinearLayout>

更新

因为我正在处理 PDF 以从视图生成 PDF,但无法生成 PDF,所以我发布了这个问题。

但是现在,我找到了使用 Webview 生成 PDF 的解决方案,您可以看到我对这个问题的回答已标记为已接受。

根据我找到的解决方案,我创建了一个库来从任何字符串或任何 HTML 内容生成 PDF。

PDF 生成器库: PDF-Generator

谢谢

【问题讨论】:

  • 您是否尝试将当前显示屏幕保存为图像并附加所有图像以制作单个 pdf?
  • @Divyesh 这不起作用,因为它是一个回收器视图——整个显示器不在屏幕上。视图被回收
  • @Divyesh 请正确阅读问题。
  • 但计算滚动位置,当该位置变为顶部时,拍摄另一张屏幕图像,依此类推
  • @Divyesh:感谢您的关注和回复,但如果您有解决方案请提供,我不知道该怎么做。

标签: android pdf printing android-recyclerview


【解决方案1】:

我在这里查看了所有答案,但不幸的是,它们对我不起作用。我采用了从 StackOverflow 创建位图的方法。该方法将回收器视图作为参数并将其转换为位图,然后由 PdfDocument.pageInfo 使用以使其满足您的需求。我试过了,它适用于所有布局,例如相对布局和线性布局。希望这会有所帮助。

Bitmap recycler_view_bm =     getScreenshotFromRecyclerView(mRecyclerView);

        try {

            pdfFile.createNewFile();
            FileOutputStream fOut = new FileOutputStream(pdfFile);

            PdfDocument document = new PdfDocument();
            PdfDocument.PageInfo pageInfo = new
                    PdfDocument.PageInfo.Builder(recycler_view_bm.getWidth(), recycler_view_bm.getHeight(), 1).create();
            PdfDocument.Page page = document.startPage(pageInfo);
            recycler_view_bm.prepareToDraw();
            Canvas c;
            c = page.getCanvas();
           c.drawBitmap(recycler_view_bm,0,0,null);
            document.finishPage(page);
            document.writeTo(fOut);
            document.close();
            Snackbar snackbar = Snackbar
                    .make(equipmentsRecordActivityLayout, "PDF generated successfully.", Snackbar.LENGTH_LONG)
                    .setAction("Open", new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                          openPDFRecord(pdfFile);
                        }
                    });

            snackbar.show();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public Bitmap getScreenshotFromRecyclerView(RecyclerView view) {
        RecyclerView.Adapter adapter = view.getAdapter();
        Bitmap bigBitmap = null;
        if (adapter != null) {
            int size = adapter.getItemCount();
            int height = 0;
            Paint paint = new Paint();
            int iHeight = 0;
            final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

            // Use 1/8th of the available memory for this memory cache.
            final int cacheSize = maxMemory / 8;
            LruCache<String, Bitmap> bitmaCache = new LruCache<>(cacheSize);
            for (int i = 0; i < size; i++) {
                RecyclerView.ViewHolder holder = adapter.createViewHolder(view, adapter.getItemViewType(i));
                adapter.onBindViewHolder(holder, i);
                holder.itemView.measure(View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY),
                        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
                holder.itemView.layout(0, 0, holder.itemView.getMeasuredWidth(), holder.itemView.getMeasuredHeight());
                holder.itemView.setDrawingCacheEnabled(true);
                holder.itemView.buildDrawingCache();
                Bitmap drawingCache = holder.itemView.getDrawingCache();
                if (drawingCache != null) {

                    bitmaCache.put(String.valueOf(i), drawingCache);
                }

                height += holder.itemView.getMeasuredHeight();
            }

            bigBitmap = Bitmap.createBitmap(view.getMeasuredWidth(), height, Bitmap.Config.ARGB_8888);
            Canvas bigCanvas = new Canvas(bigBitmap);
            bigCanvas.drawColor(Color.WHITE);

            for (int i = 0; i < size; i++) {
                Bitmap bitmap = bitmaCache.get(String.valueOf(i));
                bigCanvas.drawBitmap(bitmap, 0f, iHeight, paint);
                iHeight += bitmap.getHeight();
                bitmap.recycle();
            }

        }
        return bigBitmap;
    }

【讨论】:

    【解决方案2】:

    这是从视图生成 PDF 的 samble 代码

      //create bitmap from view and returns it
    private Bitmap getBitmapFromView(View view) {
        ScrollView hsv = (ScrollView) findViewById(R.id.scrollViewP);
        HorizontalScrollView horizontal = (HorizontalScrollView) findViewById(R.id.hsv);
        int totalHeight = hsv.getChildAt(0).getHeight();
        int totalWidth = horizontal.getChildAt(0).getWidth();
        Bitmap returnedBitmap = Bitmap.createBitmap(totalWidth, totalHeight,Bitmap.Config.ARGB_8888);
        //Bind a canvas to it
        Canvas canvas = new Canvas(returnedBitmap);
        //Get the view's background
        Drawable bgDrawable =view.getBackground();
        if (bgDrawable!=null) {
            //has background drawable, then draw it on the canvas
            bgDrawable.draw(canvas);
        }   else{
            //does not have background drawable, then draw white background on the canvas
            canvas.drawColor(Color.WHITE);
        }
        // draw the view on the canvas
        view.draw(canvas);
        //return the bitmap
        return returnedBitmap;
    }
    private static void addImage(Document document,byte[] byteArray)
    {
        Image image = null;
        try
        {
            image = Image.getInstance(byteArray);
        }
        catch (BadElementException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (MalformedURLException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // image.scaleAbsolute(150f, 150f);
        try
        {
            document.add(image);
        } catch (DocumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public void CreatePDF()
    {
    
        File folder = new File(Environment.getExternalStorageDirectory()+File.separator+"PDF Folder");
        folder.mkdirs();
    
       Date date = new Date() ;
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(date);
    
       final File myFile = new File(folder + timeStamp + ".pdf");
        try {
            OutputStream output  = new FileOutputStream(myFile);
            Document document = new Document(PageSize.A4);
            try{
                PdfWriter.getInstance(document, output);
                document.open();
              LinearLayout view2 = (LinearLayout)findViewById(R.id.MainLayout);
    
                view2.setDrawingCacheEnabled(true);
                Bitmap screen2= getBitmapFromView(view2);
                ByteArrayOutputStream stream2 = new ByteArrayOutputStream();
                screen2.compress(Bitmap.CompressFormat.JPEG,100, stream2);
                byte[] byteArray2 = stream2.toByteArray();
                addImage(document,byteArray2);
    
                    document.close();
                    AlertDialog.Builder builder =  new AlertDialog.Builder(PaySlip.this, R.style.AppCompatAlertDialogStyle);
                    builder.setTitle("Success")
                            .setMessage("enter code herePDF File Generated Successfully.")
                            .setIcon(android.R.drawable.ic_dialog_alert)
                            .setPositiveButton(android.R.string.ok,new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int whichButton)
                                {
                                    Intent intent = new Intent(Intent.ACTION_VIEW);
                                    intent.setDataAndType(Uri.fromFile(myFile), "application/pdf");
                                    intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                                    startActivity(intent);
                                }
    
                            }).show();
    
                //document.add(new Paragraph(mBodyEditText.getText().toString()));
            }catch (DocumentException e)
            {
                //loading.dismiss();
                e.printStackTrace();
            }
    
        }catch (FileNotFoundException e)
        {
           // loading.dismiss();
          e.printStackTrace();
        }
    
    
    }
    

    【讨论】:

    • 不工作!!我想从 recycler-view 创建 PDF。
    • 将携带recyclerview的view转为bitmap,再将bitmap转为pdf文件。我正在使用上面的代码,它的工作完美
    • 您具体遇到了哪些挑战?
    【解决方案3】:

    其中viewRecyclerView 的实例:

    view.measure(
                 View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY),
                 View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    
    myBitmap = Bitmap.createBitmap(view.getWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
    

    【讨论】:

      【解决方案4】:

      经过大量解决方法和解决方案后,我得到了解决方案,以及实现此目标的最佳方法,

      在 webview 中以 html 形式添加您的内容,从 webview 我们可以直接使用 Android 的 PrintManager 类进行打印。

      像这样:

      String documentName = "yourDocumentName"; // you can provide any name
      
      // Get a PrintManager instance
      PrintManager printManager = (PrintManager) context.getSystemService(PRINT_SERVICE);
      
      // Get a print adapter instance
      PrintDocumentAdapter printAdapter = webView.createPrintDocumentAdapter(documentName);
      
      PrintJob printJob = printManager.print(documentName, printAdapter, new PrintAttributes.Builder().build());
      

      上面是打印webview内容的示例代码,使用它我们也可以生成PDF。

      更多信息和使用请参考Printing HTML Document

      谢谢。

      【讨论】:

      • 这真的是您问题的答案吗?我们如何将回收站视图内容转换为 PDF?您提供的库只讨论字符串或 HTML 内容,对吗?我们首先如何将回收站视图内容转换为 HTML?
      • 我没有得到将回收视图内容转换为 HTML 的解决方案,因此找到了替代解决方案,我将整个内容转换为 HTML,然后生成了 PDF。所以我为它创建了一个库。
      猜你喜欢
      • 2015-03-17
      • 2015-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-24
      • 2012-06-10
      • 1970-01-01
      • 2016-11-11
      相关资源
      最近更新 更多