🧾

AndroidでWebView画面をPDF保存する

2022/10/07に公開

はじめに

はじめまして、2022年4月よりスペースマーケットでアプリエンジニアを担当していますseoと申します。

弊社では「スペースシェアをあたりまえに」をMISSIONに、スペースシェアのプラットフォーム事業を運営しております。

その中で、法人のお客様のご利用も多く、利用前の見積書や利用後の領収書発行のニーズもたくさんございます。

今回は、見積書や領収書などWebView画面をPDFファイルとして、ローカルストレージへ保存する機能を実装しましたので、実装の中身(Android編)をご紹介できたらと思います!

最新版アプリにてご利用できますので、ぜひこちらのリンクよりダウンロードして、たくさんの素敵なスペースを利用してみてください✨

ゴール

予約一覧画面から「領収書を表示する」ボタンを押すと、

WebViewの領収書が表示され、

メニューから「PDFをダウンロード」を選択すると、

保存する画面が出てきます

実装してみよう

まずは、PDF化したWebViewを表示するActivityの作成です。
(Jetpack Composeでの記事はまたの機会に🙇‍♂️)

それぞれonCreate内のメソッドの役割を見ていきましょう!

class PdfWebActivity : AppCompatActivity() {

    companion object {
        private const val KEY_URL: String = "KEY_URL"
        fun openUrl(from: Context, url: String) {
            Intent(from, PdfWebActivity::class.java).let {
                it.putExtra(KEY_URL, url)
                from.startActivity(it)
            }
        }
    }
    
    private lateinit var binding: ActivityWebBinding
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = DataBindingUtil.setContentView(this, R.layout.activity_web)
        loadUrl()
        setActionBar()
        setViewPortrait()
    }
}

WebViewに表示するurlのload処理ですね。

private fun loadUrl() {
    val url = intent.getStringExtra(KEY_URL) ?: return
    binding.webView.loadUrl(url)
}

「PDFを保存する」ボタンを表示するために、ActionBarとメニューボタンを設置します。
また、メニューボタンの項目をxmlファイルで作成しておきます。

private fun setActionBar() {
    setSupportActionBar(toolbar)
    supportActionBar?.run {
        setDisplayHomeAsUpEnabled(true)
        setHomeButtonEnabled(true)
    }
}

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.web_receipt, menu)
    return true
}

表示するWeb画面がスマホサイズにレスポンシブ対応していないときは、こちらの設定を有効にすることをオススメします。いい感じにwidthをそろえてくれます。

private fun setViewPortrait() {
    binding.webView.apply {
	settings.javaScriptEnabled = true
        settings.useWideViewPort = true
        settings.loadWithOverviewMode = true
        settings.builtInZoomControls = true
        setInitialScale(1)
    }
}

これでPDF化したいWebViewを表示することができました。

ここからがメインディッシュです!

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    when (item.itemId) {
        R.id.menu_download_pdf -> {
            val adapter = binding.webView.createPrintDocumentAdapter("保存したいファイル名"))
            val printManager = getSystemService(PRINT_SERVICE) as PrintManager
            printManager.print("Document", adapter, PrintAttributes.Builder().build())
        }
    }
    return true
}

メニューボタンを押した時の動作を設定するoverride fun onOptionsItemSelectedにて、今回はmenu_download_pdfを押下時に、PDF保存やプリントの設定ができるPrintManagerクラスをよびだします。

https://developer.android.com/reference/android/print/PrintManager

とういう形で、実質たった3行でPDF化をPrintManagerにまかせることができます。

この機能の実装前は、CS部門の方々が日々、問い合わせごとにメールなどで対応されていたとのことで、本当に必要な業務に集中できるようになってよかったです!
CS部門の方々、日々のご対応ありがとうございます🙇‍♂️

最後に

スペースマーケットでは一緒に働く仲間を募集中です!
弊社は、iOS/Android/Flutterと3つのアプリが存在するので、アプリエンジニアとしての総合力を向上させることができる環境です!
ぜひ、ご応募お待ちしております!!

https://spacemarket.co.jp/recruit/engineer/

スペースマーケット Engineer Blog

Discussion