PdfDocument document = new PdfDocument();
// crate a page description
PageInfo pageInfo = new PageInfo.Builder(300, 300, 1).create();
// create a new page from the PageInfo
Page page = document.startPage(pageInfo);
// repaint the user's text into the page
View content = findViewById(R.id.textarea);
content.draw(page.getCanvas());
// do final processing of the page
document.finishPage(page);
try {
File f = getPDFPath();
FileOutputStream fos = new FileOutputStream(f);
document.writeTo(fos);
document.close();
fos.close();
} catch (IOException e) {
throw new RuntimeException("Error generating file", e);
}
findViewById(R.id.textarea);
引用带有某些文字的TextView
,但上面的代码只生成空pdf。可能是什么问题?
是否有任何链接有使用Android原生API生成pdf的工作样本?
答案 0 :(得分:12)
我有,但经过大量测试后,我意识到我的视图是0高度和0宽度,因为我使用的是TextView。 所以我设法等到视图(TextView)将加载并在开始创建文档后,看一下代码,希望你能解决它:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
final TextView tv = (TextView) findViewById(R.id.textView1);
ViewTreeObserver vto = tv.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Toast.makeText(MainActivity.this, tv.getWidth() + " x " + tv.getHeight(), Toast.LENGTH_LONG).show();
try {
File file1 = new File("/mnt/sdcard/test/");
if(!file1.exists()){
file1.mkdirs();
}
File file = new File("/mnt/sdcard/test", "filename"+System.currentTimeMillis()+".pdf");
PrintAttributes printAttrs = new PrintAttributes.Builder().
setColorMode(PrintAttributes.COLOR_MODE_COLOR).
setMediaSize(PrintAttributes.MediaSize.ISO_A4).
setResolution(new Resolution("zooey", PRINT_SERVICE, 450, 700)).
setMinMargins(Margins.NO_MARGINS).
build();
PdfDocument document = new PrintedPdfDocument(MainActivity.this, printAttrs);
PageInfo pageInfo = new PageInfo.Builder(450, 700, 1).create();
Page page = document.startPage(pageInfo);
if (page != null) {
View view = findViewById(R.id.textView1);//getContentView();
view.layout(0, 0, view.getWidth(),
view.getHeight());
Log.i("draw view", " content size: "+view.getWidth()+" / "+view.getHeight());
view.draw(page.getCanvas());
// Move the canvas for the next view.
page.getCanvas().translate(0, view.getHeight());
}
document.finishPage(page);
os = new FileOutputStream(file);
document.writeTo(os);
document.close();
os.close();
Log.i("done", file.getAbsolutePath().toString());
} catch (IOException e) {
throw new RuntimeException("Error generating file", e);
}
tv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
}
里面的魔力:
final TextView tv = (TextView) findViewById(R.id.textView1);
ViewTreeObserver vto = tv.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// create document here
}
});
答案 1 :(得分:4)
如果某人正在动态创建布局,并且没有将其视图附加到活动或片段,这些活动或片段在活动或片段生命周期的某个时刻被渲染和测量,则还有另一种方法:
rootView.measure(800, 480);
rootView.layout(0, 0, 800, 480);
这样你的rootView宽度和高度就不会保持为0,并且会有一些东西会被渲染到文档中。感谢the answer here!
答案 2 :(得分:2)
最能帮助我的例子就是Android Cookbook中可以找到的那个例子。 您可以在github account。
中找到相应的代码将该代码与用于编写的代码混合,您将拥有它:
@TargetApi(Build.VERSION_CODES.KITKAT)
public void run() {
// Create a shiny new (but blank) PDF document in memory
// We want it to optionally be printable, so add PrintAttributes
// and use a PrintedPdfDocument. Simpler: new PdfDocument().
PrintAttributes printAttrs = new PrintAttributes.Builder().
setColorMode(PrintAttributes.COLOR_MODE_COLOR).
setMediaSize(PrintAttributes.MediaSize.NA_LETTER).
setResolution(new PrintAttributes.Resolution("zooey", PRINT_SERVICE, 300, 300)).
setMinMargins(PrintAttributes.Margins.NO_MARGINS).
build();
PdfDocument document = new PrintedPdfDocument(this, printAttrs);
// crate a page description
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(300, 300, 1).create();
// create a new page from the PageInfo
PdfDocument.Page page = document.startPage(pageInfo);
// repaint the user's text into the page
View content = findViewById(R.id.textArea);
content.draw(page.getCanvas());
// do final processing of the page
document.finishPage(page);
// Here you could add more pages in a longer doc app, but you'd have
// to handle page-breaking yourself in e.g., write your own word processor...
// Now write the PDF document to a file; it actually needs to be a file
// since the Share mechanism can't accept a byte[]. though it can
// accept a String/CharSequence. Meh.
try {
File f = new File(Environment.getExternalStorageDirectory().getPath() + "/pruebaAppModerator.pdf");
FileOutputStream fos = new FileOutputStream(f);
document.writeTo(fos);
document.close();
fos.close();
} catch (IOException e) {
throw new RuntimeException("Error generating file", e);
}
}
答案 3 :(得分:0)
我有完全相同的问题,但为了实现@ user2021505解决方案(有效)我应该做一个主要的重构,所以我这样解决了问题
// ...
PdfDocument.Page page = document.startPage(pageInfo);
TextView textView = new TextView(ctx);
textView.setText("1,2,3");
// here the solution
int left = 0;
int top = 0;
int width = 200;
int height = 200;
textView.layout(0,0,width,height);
canvas.save()
canvas.translate(left,top);
textView.draw(page.getCanvas());
canvas.restore()
答案 4 :(得分:0)
首先需要添加依赖
implementation group: 'com.itextpdf', name: 'itextpdf', version: '5.3.2'
然后在空白的 PDF 文档上设置位图
PdfDocument pdfDocument = new PdfDocument();
PdfDocument.PageInfo pi = new
PdfDocument.PageInfo.Builder(mBitmap.getWidth(),
mBitmap.getHeight(),1).create();
PdfDocument.Page page = pdfDocument.startPage(pi);
Canvas canvas = page.getCanvas();
Paint paint = new Paint();
paint.setColor(Color.parseColor("#FFFFFF"));
canvas.drawPaint(paint);
mBitmap = Bitmap.createScaledBitmap(mBitmap,
mBitmap.getWidth(),mBitmap.getHeight(), true);
paint.setColor(Color.BLUE);
canvas.drawBitmap(mBitmap,0,0,null);
pdfDocument.finishPage(page);
pdfDocument.close();